/* * "$Id: fltkpqi.cc,v 1.34 2007-02-19 20:30:05 rmf24 Exp $" * * FltkGUI for RetroShare. * * Copyright 2004-2006 by Robert Fernie. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License Version 2 as published by the Free Software Foundation. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to "retroshare@lunamutt.com". * */ #include "dbase/filedex.h" #include "server/filedexserver.h" #include "pqi/pqipersongrp.h" #include "pqi/pqiloopback.h" #include "fltkgui/guitab.h" #include "fltkgui/fltkserver.h" #include #include #include // Includes for directory creation. #include #include #include // Conflicts with FLTK def - hope they are the same. //#include // for blocking signals #include #include "fltkgui/alertbox.h" #include "pqi/pqidebug.h" // key callback functions. void gui_update(); void update_connections(); void update_search(); void update_messages(); void update_about(); void update_files(); // Global Pointers for the callback functions. fltkserver *fserv; UserInterface *ui; alertBox *chatbox; alertBox *alertbox; // initial configuration bootstrapping... static const std::string config_init_file = "default_cert.txt"; static const std::string config_file = "config.rs"; static const std::string cert_dir = "friends"; static const std::string key_dir = "keys"; static const std::string ca_file = "cacerts.pem"; static std::string config_basedir; static std::string load_cert; static std::string load_key; static std::string load_trustedpeer_file; static bool load_trustedpeer = false; static bool firsttime_run = false; int create_configinit(); int check_create_directory(std::string dir); void load_check_basedir(); void clear_passwds(); /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS static const char dirSeperator = '/'; // For unix. // standard start for unix. int main(int argc, char **argv) { // setup debugging for desired zones. setOutputLevel(PQL_WARNING); // default to Warnings. // For Testing purposes. // We can adjust everything under Linux. //setZoneLevel(PQL_DEBUG_BASIC, 38422); // pqipacket. //setZoneLevel(PQL_DEBUG_BASIC, 96184); // pqinetwork; //setZoneLevel(PQL_DEBUG_BASIC, 82371); // pqiperson. //setZoneLevel(PQL_DEBUG_BASIC, 60478); // pqitunnel. //setZoneLevel(PQL_DEBUG_BASIC, 34283); // pqihandler. //setZoneLevel(PQL_DEBUG_BASIC, 44863); // discItems. //setZoneLevel(PQL_DEBUG_BASIC, 2482); // p3disc //setZoneLevel(PQL_DEBUG_BASIC, 1728); // pqi/p3proxy //setZoneLevel(PQL_DEBUG_BASIC, 1211); // sslroot. //setZoneLevel(PQL_DEBUG_BASIC, 37714); // pqissl. //setZoneLevel(PQL_DEBUG_BASIC, 8221); // pqistreamer. //setZoneLevel(PQL_DEBUG_BASIC, 9326); // pqiarchive //setZoneLevel(PQL_DEBUG_BASIC, 3334); // p3channel. //setZoneLevel(PQL_DEBUG_BASIC, 354); // pqipersongrp. //setZoneLevel(PQL_DEBUG_BASIC, 6846); // pqiudpproxy //setZoneLevel(PQL_DEBUG_BASIC, 3144); // pqissludp; //setZoneLevel(PQL_DEBUG_BASIC, 86539); // pqifiler. //setZoneLevel(PQL_DEBUG_BASIC, 91393); // Funky_Browser. //setZoneLevel(PQL_DEBUG_BASIC, 25915); // fltkserver //setZoneLevel(PQL_DEBUG_BASIC, 47659); // fldxsrvr //setZoneLevel(PQL_DEBUG_BASIC, 49787); // pqissllistener /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #else static const char dirSeperator = '\\'; // For windows. // Include for the windows system tray... // the reason for the alternative // program start. #include "retroTray.h" /* believe this fn exists! */ LPSTR * WINAPI CommandLineToArgvA(LPCSTR,int*); const int MAX_ARGS = 32; int WinMain(HINSTANCE hinst, HINSTANCE prevhinst, char *argv_crap, int argc_crap) { int i,j; int argc; char *argv[MAX_ARGS]; char *wholeline = GetCommandLine(); int cmdlen = strlen(wholeline); // duplicate line, so we can put in spaces.. char dupline[cmdlen+1]; strcpy(dupline, wholeline); /* break wholeline down .... * NB. This is very simplistic, and will not * handle multiple spaces, or quotations etc, only for debugging purposes */ argv[0] = dupline; for(i = 1, j = 0; (j + 1 < cmdlen) && (i < MAX_ARGS);) { /* find next space. */ for(;(j + 1 < cmdlen) && (dupline[j] != ' ');j++); if (j + 1 < cmdlen) { dupline[j] = '\0'; argv[i++] = &(dupline[j+1]); } } argc = i; for( i=0; i dirs; short port = 7812; // default port. bool forceLocalAddr = false; bool haveLogFile = false; bool outStderr = false; char inet[256] = "127.0.0.1"; char passwd[256] = ""; char logfname[1024] = ""; int c; bool havePasswd = false; bool haveDebugLevel = false; int debugLevel = PQL_WARNING; bool udpListenerOnly = false; while((c = getopt(argc, argv,"i:p:c:sw:l:d:u")) != -1) { switch (c) { case 'l': strncpy(logfname, optarg, 1024); std::cerr << "LogFile (" << logfname; std::cerr << ") Selected" << std::endl; haveLogFile = true; break; case 'w': strncpy(passwd, optarg, 256); std::cerr << "Password Specified(" << passwd; std::cerr << ") Selected" << std::endl; havePasswd = true; break; case 'i': strncpy(inet, optarg, 256); std::cerr << "New Inet Addr(" << inet; std::cerr << ") Selected" << std::endl; forceLocalAddr = true; break; case 'p': port = atoi(optarg); std::cerr << "New Listening Port(" << port; std::cerr << ") Selected" << std::endl; break; case 'c': config_basedir = optarg; std::cerr << "New Base Config Dir("; std::cerr << config_basedir; std::cerr << ") Selected" << std::endl; break; case 's': outStderr = true; haveLogFile = false; std::cerr << "Output to Stderr"; std::cerr << std::endl; break; case 'd': haveDebugLevel = true; debugLevel = atoi(optarg); std::cerr << "Opt for new Debug Level"; std::cerr << std::endl; break; case 'u': udpListenerOnly = true; std::cerr << "Opt for only udpListener"; std::cerr << std::endl; break; default: std::cerr << "Unknown Option!"; exit(1); } } // set the default Debug Level... if (haveDebugLevel) { if ((debugLevel > 0) && (debugLevel <= PQL_DEBUG_ALL)) { std::cerr << "Setting Debug Level to: " << debugLevel; std::cerr << std::endl; setOutputLevel(debugLevel); } else { std::cerr << "Ignoring Invalid Debug Level: "; std::cerr << debugLevel; std::cerr << std::endl; } } // set the debug file. if (haveLogFile) { setDebugFile(logfname); } /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ #else // As windows doesn't have commandline options - we have to set them... // or make them part of prog config. /* char certloc[256] = "./keys/bobby_cert.pem"; char pkeyloc[256] = "./keys/bobby_pk.pem"; */ //char inet[256] = "10.0.0.2"; // only the currnet directory for the moment. //dirs.push_back("."); // Windows Networking Init. WORD wVerReq = MAKEWORD(2,2); WSADATA wsaData; if (0 != WSAStartup(wVerReq, &wsaData)) { std::cerr << "Failed to Startup Windows Networking"; std::cerr << std::endl; } else { std::cerr << "Started Windows Networking"; std::cerr << std::endl; } #endif /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ // first check config directories, and set bootstrap values. load_check_basedir(); // blank the trustedpeer loading variables. load_trustedpeer = false; load_trustedpeer_file = ""; firsttime_run = false; // Next - Setup the GUI defaults...... ui = new UserInterface(); ui -> make_windows(); // SWITCH off the SIGPIPE - kills process on Linux. /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS struct sigaction sigact; sigact.sa_handler = SIG_IGN; sigact.sa_flags = 0; if (0 == sigaction(SIGPIPE, &sigact, NULL)) { std::cerr << "RetroShare:: Successfully Installed"; std::cerr << "the SIGPIPE Block" << std::endl; } else { std::cerr << "RetroShare:: Failed to Install"; std::cerr << "the SIGPIPE Block" << std::endl; } #else // in windows case, install the system tray. std::string iconpath = config_basedir + dirSeperator; iconpath += "tst.ico"; SetIconPath(iconpath.c_str()); InitialiseRetroTray(hinst, NULL, ui); #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ // add the text_buffers to the correct displays... ui -> cert_details -> buffer(new Fl_Text_Buffer(10000)); ui -> msg_details -> buffer(new Fl_Text_Buffer(10000)); ui -> msg_text -> buffer(new Fl_Text_Buffer(10000)); ui -> transfer_overview -> buffer(new Fl_Text_Buffer(10000)); ui -> chan_createmsg_msg -> buffer(new Fl_Text_Buffer(10000)); ui -> chan_msgdetails_msg -> buffer(new Fl_Text_Buffer(10000)); ui -> alert_box -> buffer(new Fl_Text_Buffer(10000)); ui -> chatter_box -> buffer(new Fl_Text_Buffer(10000)); //ui -> cert_list -> Fl_Browser::handle(FL_PUSH); ui -> cert_list -> when(FL_WHEN_CHANGED); ui -> srch_results -> when(FL_WHEN_CHANGED); ui -> msg_list -> when(FL_WHEN_CHANGED); ui -> cert_list -> setCheck(2); // ui -> cert_list -> setTitle(0,"Status"); // ui -> cert_list -> setTitle(1,"Person"); // ui -> cert_list -> setTitle(2,"Auto Connect"); // ui -> cert_list -> setTitle(3,"Server"); // // // ui -> srch_results -> setTitle(0,"Source"); // ui -> srch_results -> setTitle(1,"KeyWord"); // ui -> srch_results -> setTitle(2,"FileName"); // ui -> srch_results -> setTitle(3,"Size"); // // // ui -> msg_list -> setTitle(0,"Source"); // ui -> msg_list -> setTitle(1,"Message"); // ui -> msg_list -> setTitle(2,"Date"); // // ui -> transfer_downloads -> setTitle(0,"Source"); // ui -> transfer_downloads -> setTitle(1,"Direction"); // ui -> transfer_downloads -> setTitle(2,"Filename"); // ui -> transfer_downloads -> setTitle(3,"Completed"); // ui -> transfer_downloads -> setTitle(4,"Rate"); // disable the channel stuff (and recommend stuff) for now! ui ->file_channel_button->deactivate(); ui ->search_channel_button->deactivate(); //ui ->channels->deactivate(); chatbox = new chatterBox(ui->chatter_window, ui->chatter_box); alertbox = new alertBox(ui->alert_window,ui->alert_box); //static int neighbour_widths[3] = { 150, 250, 0 }; //ui -> cert_neighbour_list -> column_widths(neighbour_widths); static int neighbour_widths[3] = { 150, 250, 0 }; ui -> neigh_signers -> column_widths(neighbour_widths); ui -> file_chooser -> preview(0); // Next bring up the welcome window..... // load up the default welcome settings. //ui -> load_cert -> value(load_cert.c_str()); //ui -> load_key -> value(load_key.c_str()); std::string userName; bool existingUser = false; if (LoadCheckXPGPandGetName(load_cert.c_str(), userName)) { ui -> load_name -> value(userName.c_str()); existingUser = true; } else { ui -> load_name -> value("No Existing User -> Create New"); } //ui -> gen_basename -> value("user"); ui -> welcome_window -> show(); if (existingUser) { ui -> load_passwd -> take_focus(); } else { ui -> gen_name -> take_focus(); } alertbox ->sendMsg(0, 10, "RetroShare GUI Loading.", ""); alertbox ->sendMsg(0, 10, "RetroShare: Alert Msgs activated", ""); /* do a null init to allow the SSL libray to startup! */ /**************** PQI_USE_XPGP ******************/ #if defined(PQI_USE_XPGP) /* do a null init to allow the SSL libray to startup! */ getSSLRoot() -> initssl(NULL, NULL, NULL); #else /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ getSSLRoot() -> initssl(NULL, NULL, NULL, NULL); #endif /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS if (havePasswd) { ui -> load_passwd -> value(passwd); load_existing(NULL, NULL); // do we need to shut down the window? } /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #else // WINDOWS // can't load passwd from command line. #endif // wait for this window to be finished.... while(!(getSSLRoot() -> active())) { Fl::wait(); } // ssl root is setup already.... by welcome_window. // this means that the cert/key + cacerts have been loaded. sslroot *sr = getSSLRoot(); /**************** PQI_USE_XPGP ******************/ #if defined(PQI_USE_XPGP) if (1 != sr -> initssl(NULL, NULL, NULL)) #else /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ if (1 != sr -> initssl(NULL, NULL, NULL, NULL)) #endif /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ { std::cerr << "main() - Fatal Error....." << std::endl; std::cerr << "Invalid Certificate configuration!" << std::endl; std::cerr << std::endl; exit(1); } /* set the debugging to crashMode */ if ((!haveLogFile) && (!outStderr)) { std::string crashfile = config_basedir + dirSeperator; crashfile += "retro.log"; setDebugCrashMode(crashfile.c_str()); } alertbox ->sendMsg(0, 10, "RetroShare: Loading", ""); // set the directories for full configuration load. sr -> setConfigDirs(config_basedir.c_str(), cert_dir.c_str()); sr -> loadCertificates(config_file.c_str()); sr -> checkNetAddress(); // filedex server. filedexserver server; #ifdef USE_FILELOOK fileLook *fl = new fileLook(); fl -> start(); /* background look thread */ server.setFileLook(fl); #else /*********************************************************************/ filedex *fd = new filedex(); server.setFileDex(fd); #endif server.setConfigDir(config_basedir.c_str()); SecurityPolicy *none = secpolicy_create(); if (forceLocalAddr) { struct sockaddr_in laddr; laddr.sin_family = AF_INET; laddr.sin_port = htons(port); // universal laddr.sin_addr.s_addr = inet_addr(inet); // unix specific //inet_aton(inet, &(laddr.sin_addr)); cert *own = sr -> getOwnCert(); if (own != NULL) { own -> localaddr = laddr; } } /* must load the trusted_peer before setting up the pqipersongrp */ if (firsttime_run) { /* at this point we want to load and start the trusted peer -> if selected */ if (load_trustedpeer) { /* sslroot does further checks */ sr -> loadInitialTrustedPeer(load_trustedpeer_file); } } unsigned long flags = 0; if (udpListenerOnly) { flags |= PQIPERSON_NO_SSLLISTENER; } pqipersongrp psg(none, sr, flags); psg.load_config(); server.setSearchInterface(&psg, sr); #ifdef PQI_USE_CHANNELS server.setP3Channel(psg.getP3Channel()); #endif // create loopback device, and add to pqisslgrp. SearchModule *mod = new SearchModule(); pqiloopback *ploop = new pqiloopback(); mod -> smi = 1; mod -> pqi = ploop; mod -> sp = secpolicy_create(); psg.AddSearchModule(mod); //autoDiscovery ad(&psg, sr); //ad.load_configuration(); //ad.localSetup(); fltkserver ncs; fserv = &ncs; ncs.setuppqissl(&server, &psg, sr, ui); ncs.addAlerts(alertbox, chatbox); // Set Default Save Dir. pre-load // Load from config will overwrite... std::string hdefpath = fserv -> getHomePath(); server.setSaveDir(hdefpath.c_str()); // load the GUI browser settings from sslroot. ncs.cert_load_gui_config(); server.load_config(); ncs.addAutoDiscovery(psg.getP3Disc()); // load up the help page std::string helppage = config_basedir + dirSeperator; //helppage += "html"; //helppage += dirSeperator; //helppage += "retro_help.html"; helppage += "retro.htm"; //helppage += "index.html"; //helppage = "/home/rmf24/prog/src/FLTK/fltk-1.1.6/documentation/index.html"; // Temp remove about page. ui -> help_view -> load(helppage.c_str()); ui -> help_view -> textsize(14); alertbox ->sendMsg(0, 10, "RetroShare: Loaded", ""); /* finally show the main window */ ui -> main_win -> show(); if (firsttime_run) { /* change any gui options that should be setup for the initial run */ /* set the help to be the default visible tab */ ui -> gui_tabs->value(ui->about_help_tab); } else { /* make connect gui the initial tab */ ui -> gui_tabs->value(ui->connect_tab); } ncs.init(); ncs.run(); return 1; } /* Neighbour Fns. */ void cert_neighbour_list_select(Fl_Funky_Browser*, void*) { fserv -> cert_neighbour_item_ok = false; std::cerr << "cert_neighbour_list_select() callback!" << std::endl; return; } void cert_neigh_signers_select(Fl_Browser*, void*) { std::cerr << "cert_neigh_signers_select() callback!" << std::endl; } void neigh_auth_callback(Fl_Input*, void*) { fserv -> neigh_update_auth(); return; } /* Cert fns */ void cert_list_select(Fl_Funky_Browser*, void*) { fserv -> cert_item_ok = false; // check if this was called by ticking the box. fserv -> cert_check_auto(); std::cerr << "cert_list_select() callback!" << std::endl; return; } void cert_move_to_friends(Fl_Button*, void*) { fserv -> cert_add_neighbour(); std::cerr << "cert_move_to_friend() callback!" << std::endl; return; } void cert_show_config(Fl_Button*, void*) { ui -> cert_config -> show(); return; } void cert_hide_config(Fl_Button*, void*) { ui -> cert_config -> hide(); return; } void cert_show_neighbour_config(Fl_Button*, void*) { //ui -> cert_neighbour_config -> show(); return; } void cert_hide_neighbour_config(Fl_Button*, void*) { //ui -> cert_neighbour_config -> hide(); return; } void cert_allow_change(Fl_Check_Button*, void*) { if (ui -> cert_allow -> value() == 0) { fserv -> cert_deny_current(); } else { fserv -> cert_allow_current(); } fserv -> cert_list_ok = false; fserv -> cert_item_ok = false; return; } void cert_listen_change(Fl_Check_Button*, void*) { fserv -> cert_listen_current(); fserv -> cert_list_ok = false; fserv -> cert_item_ok = false; return; } void cert_connect_change(Fl_Check_Button*, void*) { fserv -> cert_connect_current(); fserv -> cert_list_ok = false; fserv -> cert_item_ok = false; return; } void cert_auth_callback(Fl_Input*, void*) { fserv -> cert_update_auth(); return; } void cert_save_servaddr(Fl_Button*, void*) { // if success - update gui. // else leave for error message. if (0 != fserv -> cert_save_servaddr()) { fserv -> cert_item_ok = false; } return; } void cert_save_n_connect(Fl_Button*, void*) { if (0 != fserv -> cert_saveaddr_connect()) { fserv -> cert_item_ok = false; } return; } void cert_save_config(Fl_Button*, void*) { /* fserv -> cert_save_config(config_file.c_str()); */ // To allow autosave. fserv -> cert_save_config(); std::cerr << "fserv -> cert_save_config() Done!" << std::endl; return; } void cert_remove_cert(Fl_Button*, void*) { fserv -> cert_remove_current(); fserv -> cert_list_ok = false; fserv -> cert_item_ok = false; return; } void cert_trust_person_change(Fl_Check_Button*, void*) { std::cerr << "cert_trust_person_change()" << std::endl; /* at this point we ask the sslroot->tosign(current *) */ fserv -> cert_trust_current_toggle(); return; } void cert_auto_change(Fl_Check_Button*, void*) { std::cerr << "cert_auto_change()" << std::endl; fserv -> cert_toggle_auto(); return; } void cert_local_change(Fl_Check_Button*, void*) { std::cerr << "cert_local_change()" << std::endl; //fserv -> cert_toggle_auto(); return; } void cert_sign(Fl_Button*, void*) { std::cerr << "cert_sign()" << std::endl; /* at this point we ask the sslroot->tosign(current *) */ fserv -> cert_sign_current(); return; } void msg_send(Fl_Button*, void*) { fserv -> msg_send(); ui -> msg_dialog -> hide(); return; } void msg_select(Fl_Funky_Browser*, void*) { fserv -> msg_list_ok = false; fserv -> msg_item_ok = false; return; } void msg_toggle_select(Fl_Button*, void*) { return; } void msg_dialog_hide(Fl_Button*, void*) { ui -> msg_dialog -> hide(); return; } void msg_dialog_show(Fl_Button*, void*) { ui -> msg_dialog -> show(); return; } void msg_remove(Fl_Button*, void*) { fserv -> msg_remove(); fserv -> msg_list_ok = false; fserv -> msg_item_ok = false; return; } void msg_dialog_reply(Fl_Button*, void*) { fserv -> msg_reply(); fserv -> msg_item_ok = false; ui -> msg_dialog -> show(); return; } void msg_get_recommendation(Fl_Button*, void*) { fserv -> download_recommend(); return; } void channel_select(Fl_Browser*, void*) { std::cerr << "Channel callback" << std::endl; fserv -> msg_channel_select(); } void transfer_select(Fl_Funky_Browser*, void*) { std::cerr << "Transfer callback" << std::endl; //fserv -> transfer_select(); } void file_transfer_cancel(Fl_Button*, void*) { std::cerr << "File Transfer Cancel callback" << std::endl; fserv -> transfer_cancel(); } void file_transfer_clear(Fl_Button*, void*) { std::cerr << "File Transfer Clear callback" << std::endl; fserv -> transfer_clear(); } void file_transfer_total_rate(Fl_Counter*, void*) { std::cerr << "File Transfer Total Rate callback" << std::endl; fserv -> transfer_rates(); } void file_transfer_indiv_rate(Fl_Counter*, void*) { std::cerr << "File Transfer Individual Rate callback" << std::endl; fserv -> transfer_rates(); } void file_transfers_max(Fl_Counter*, void*) { std::cerr << "File Transfer Max callback" << std::endl; fserv -> transfer_rates(); } void do_new_search(Fl_Input *, void*) { fserv -> search_new(); return; } void do_search_button(Fl_Button *, void*) { fserv -> search_new(); return; } void search_remove(Fl_Button*, void*) { fserv -> search_remove(); return; } void search_result_select(Fl_Funky_Browser*, void*) { fserv -> result_item_ok = false; std::cerr << "search_result_select() callback!" << std::endl; return; } void search_download(Fl_Button*, void*) { fserv -> search_download(); return; } void search_recommend(Fl_Button*, void*) { fserv -> search_recommend(); return; } void gui_hide(Fl_Button*, void*); void gui_quit(Fl_Button*a, void*b) { gui_hide(a,b); //exit(1); return; } void gui_hide(Fl_Button*, void*) { // Temp use to shown chatter window. // ui -> chatter_window -> show(); /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS // iconize. ui -> main_win -> iconize(); #else // windows we can hide (cos the system tray is still there) ui -> main_win -> hide(); #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ return; } void file_import(Fl_Button*, void*) { fserv -> file_select(FILE_CHOOSER_IMPORT); ui -> file_chooser -> show(); return; } void file_export(Fl_Button*, void*) { fserv -> file_select(FILE_CHOOSER_EXPORT); ui -> file_chooser -> show(); return; } /* Have to fix buggy Fl_File_Chooser Code..... * Forcing the use of Enter Button. * * * if valid selection..... + Enter.... * do I/O * * else add timeout. * and unhide..... */ void fc_timeout(void *); void file_chooser_select(Fl_File_Chooser *, void*v) { std::cerr << "file_chooser_select()" << std::endl; if ((Fl::event_key() == FL_Enter) && (NULL != ui -> file_chooser -> value())) { std::cerr << "file_chooser_select() Hit Enter (With Val)!" << std::endl; fserv -> file_completeIO(); ui -> file_chooser -> hide(); return; } // Else add timeout callback .... Fl::add_timeout(0.5, fc_timeout); //fserv -> file_completeIO(); //ui -> file_chooser -> hide(); } void fc_timeout(void *) { std::cerr << "fc_timeout()" << std::endl; // ignore timeout if still shown... if (ui -> file_chooser -> shown()) { std::cerr << "Visible - Ignoring fc_timeout()" << std::endl; return; } // if valid selection.... do it. if (NULL != ui -> file_chooser -> value()) { std::cerr << "Hidden + Value - Do I/O" << std::endl; fserv -> file_completeIO(); return; } // else reshow the window, std::cerr << "Hidden + No Value - re-Show" << std::endl; ui -> file_chooser -> show(); return; } void config_server_update(Fl_Check_Button*, void*) { // save the settings. fserv -> config_server_update(); return; } void config_server_change(Fl_Button*, void*) { // save the settings. fserv -> config_server_change(); return; } void config_save_dir_change(Fl_Button*, void*) { fserv -> file_select(FILE_CHOOSER_SAVEDIR); ui -> file_chooser -> show(); // save the settings. return; } void config_add_dir(Fl_Button*, void*) { fserv -> file_select(FILE_CHOOSER_DIR); ui -> file_chooser -> show(); // save the settings. return; } void config_remove_dir(Fl_Button*, void*) { fserv -> config_remove_dir(); return; } void load_passwd_callback(Fl_Input*, void*) { load_existing(NULL, NULL); return; } void load_existing(Fl_Button*, void*) { std::string cert_loc = load_cert; //ui -> load_cert -> value(); std::string key_loc = load_key; //ui -> load_key -> value(); std::string passwd = ui -> load_passwd -> value(); // hack to use the generate passwd. if (passwd == "") { passwd = ui -> gen_passwd -> value(); } if (cert_loc == "") { alertbox ->sendMsg(0, 0, "RetroShare needs a certificate", ""); return; } if (key_loc == "") { alertbox ->sendMsg(0, 0, "RetroShare needs a Key", ""); return; } if (passwd == "") { alertbox ->sendMsg(0, 0, "RetroShare needs a passwd", ""); return; } std::string std_key_dir = config_basedir + dirSeperator; std_key_dir += key_dir; // check that the key file exists....., // and if it is not in the configuration directory - copy it there. std::string ca_loc = std_key_dir + dirSeperator; ca_loc += ca_file; sslroot *sr = getSSLRoot(); /**************** PQI_USE_XPGP ******************/ #if defined(PQI_USE_XPGP) if (0 < sr -> initssl(cert_loc.c_str(), key_loc.c_str(), passwd.c_str())) #else /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ if (0 < sr -> initssl(cert_loc.c_str(), key_loc.c_str(), ca_loc.c_str(), passwd.c_str())) #endif /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ { ui -> welcome_window -> hide(); clear_passwds(); // success..... save the cert + key locations. // as the keys are good we can create a initfile load_cert = cert_loc; load_key = key_loc; create_configinit(); return; } // else clean up .... alertbox ->sendMsg(0, 0, "RetroShare Failed To Start!",""); alertbox ->sendMsg(0, 0, "Please Check File Names/Password",""); return; } void generate_certificate(Fl_Button *button, void *nuffing) { // In the XPGP world this is easy... // generate the private_key / certificate. // save to file. // // then load as if they had entered a passwd. // check basename exists. // check that passwords match. if ((strlen(ui -> gen_passwd -> value()) < 4) || (0 != strcmp(ui -> gen_passwd -> value(), ui -> gen_passwd2 -> value()))) { std::ostringstream out; out << "RetroShare cannot generate your"; out << "Certficate because:" << std::endl; out << "\tPassword is Unsatisfactory..." << std::endl; out << "\tMust be 4+ chars and entered twice" << std::endl; alertbox ->sendMsg(0, 0, out.str(), ""); return; } if (strlen(ui -> gen_name -> value()) < 3) { std::ostringstream out; out << "RetroShare cannot generate your"; out << "Certficate because:" << std::endl; out << "\tThe Name is bad..." << std::endl; out << "\tMust be 3+ chars" << std::endl; alertbox ->sendMsg(0, 0, out.str(), ""); return; } int nbits = 2048; // Create the filename. std::string basename = config_basedir; basename += dirSeperator; basename += key_dir + dirSeperator; basename += "user"; //ui -> gen_basename -> value(); std::string key_name = basename + "_pk.pem"; std::string cert_name = basename + "_cert.pem"; /**************** PQI_USE_XPGP ******************/ #if defined(PQI_USE_XPGP) if (!generate_xpgp(cert_name.c_str(), key_name.c_str(), ui -> gen_passwd2 -> value(), ui -> gen_name -> value(), "", //ui -> gen_email -> value(), ui -> gen_org -> value(), ui -> gen_loc -> value(), "", //ui -> gen_state -> value(), ui -> gen_country -> value(), nbits)) #else /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ /* UNTIL THIS IS FILLED IN CANNOT GENERATE X509 REQ */ #endif /* X509 Certificates */ /**************** PQI_USE_XPGP ******************/ { std::ostringstream out; out << "RetroShare cannot generate your"; out << "Certficate: UNKNOWN REASON!" << std::endl; alertbox ->sendMsg(0, 0, out.str(), ""); return; } /* set the load passwd to the gen version * and try to load it! */ //ui -> load_cert -> value(cert_name.c_str()); //ui -> load_key -> value(key_name.c_str()); load_cert = cert_name.c_str(); load_key = key_name.c_str(); //ui -> load_passwd -> value(ui -> load_passwd -> value()); { std::ostringstream out; out << "RetroShare has Successfully generated"; out << "a Certficate/Key" << std::endl; out << "\tCert Located: " << cert_name << std::endl; out << "\tLocated: " << key_name << std::endl; alertbox ->sendMsg(0, 10, out.str(), ""); } /* now if the user has selected to load a trusted certificate * we must save the details to we can load it in a second. * * load_trustedpeer is taken from the gen_trusted_tick_box, * while load_trusted_cert(Fl_Button*, void*) sets the load_trustedpeer_file string. */ if (1 == ui -> gen_trusted_tick_box -> value()) { load_trustedpeer = true; } else { load_trustedpeer = false; } // Also set the first time flag. firsttime_run = true; /* call standard load ! */ load_existing(button, nuffing); return; } void load_trusted_cert(Fl_Button*, void*) { Fl_File_Chooser *fc = new Fl_File_Chooser("", "Certificate File (*.{pqi})", 0, "Trusted Friend Selection"); fc -> show(); while(fc -> shown()) Fl::wait(); /* if we are successful, * 1) load certificate.... if that is successful... * 2) display name, * 3) and tick box.. */ bool valid = false; bool trustedFriend = false; std::string userName; if (fc->value()) { valid = true; load_trustedpeer_file = fc -> value(); } if ((valid) && (LoadCheckXPGPandGetName(load_trustedpeer_file.c_str(), userName))) { ui -> gen_trusted_peer -> value(userName.c_str()); ui -> gen_trusted_tick_box -> value(1); trustedFriend = true; } else { load_trustedpeer_file = ""; if (valid) { ui -> gen_trusted_peer -> value("-Bad-File-"); } else { ui -> gen_trusted_peer -> value(""); } ui -> gen_trusted_tick_box -> value(0); } delete fc; return; } void gen_trusted_tick_callback(Fl_Check_Button*, void*) { std::cerr << "gen_trusted_tick_callback()"; std::cerr << std::endl; if (ui -> gen_trusted_tick_box -> value()) { load_trusted_cert(NULL, NULL); } else { ui -> gen_trusted_peer -> value(""); } return; } void gen_load_trusted(Fl_Button*, void*) { std::cerr << "gen_load_trusted()"; std::cerr << std::endl; load_trusted_cert(NULL, NULL); return; } void load_cert_change(Fl_Button*, void*) { std::string std_key_dir = config_basedir + dirSeperator; std_key_dir += key_dir; /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifdef WINDOWS_SYS /* ONLY FOR WINDOWS */ std_key_dir = make_path_unix(std_key_dir); #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ Fl_File_Chooser *fc = new Fl_File_Chooser(std_key_dir.c_str(), "Certificate File (*.{pem})", 0, "Certificate Selection"); fc -> show(); while(fc -> shown()) Fl::wait(); //ui -> load_cert -> value(fc -> value()); delete fc; return; } void load_key_change(Fl_Button*, void*) { std::string std_key_dir = config_basedir + dirSeperator; std_key_dir += key_dir; /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifdef WINDOWS_SYS /* ONLY FOR WINDOWS */ std_key_dir = make_path_unix(std_key_dir); #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ Fl_File_Chooser *fc = new Fl_File_Chooser(std_key_dir.c_str(), "Private Key File (*.{pem})", 0, "Key Selection"); fc -> show(); while(fc -> shown()) Fl::wait(); //ui -> load_key -> value(fc -> value()); delete fc; return; } void clear_passwds() { ui -> load_passwd -> value("UNKNOWN.....0"); ui -> gen_passwd -> value("UNKNOWN.....1"); ui -> gen_passwd2 -> value("UNKNOWN.....2"); } void load_check_basedir() { // get the default configuration location. if (config_basedir == "") { // if unix. homedir + /.pqiPGPrc /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS char *h = getenv("HOME"); std::cerr << "fltkpqi::basedir() -> $HOME = "; std::cerr << h << std::endl; if (h == NULL) { std::cerr << "load_check_basedir() Fatal Error --"; std::cerr << std::endl; std::cerr << "\tcannot determine $HOME dir" < $APPDATA = "; std::cerr << h << std::endl; char *h2 = getenv("HOMEDRIVE"); std::cerr << "fltkpqi::basedir() -> $HOMEDRIVE = "; std::cerr << h2 << std::endl; char *h3 = getenv("HOMEPATH"); std::cerr << "fltkpqi::basedir() -> $HOMEPATH = "; std::cerr << h3 << std::endl; if (h == NULL) { // generating default std::cerr << "load_check_basedir() getEnv Error --Win95/98?"; std::cerr << std::endl; config_basedir="C:\\Retro"; } else { config_basedir = h; } check_create_directory(config_basedir); config_basedir += "\\RetroShare"; #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ } std::string subdir1 = config_basedir + dirSeperator; std::string subdir2 = subdir1; subdir1 += key_dir; subdir2 += cert_dir; // fatal if cannot find/create. std::cerr << "Checking For Directories" << std::endl; check_create_directory(config_basedir); check_create_directory(subdir1); check_create_directory(subdir2); // have a config directories. // Check for config file. std::string initfile = config_basedir + dirSeperator; initfile += config_init_file; // open and read in the lines. FILE *ifd = fopen(initfile.c_str(), "r"); char path[1024]; int i; if (ifd != NULL) { if (NULL != fgets(path, 1024, ifd)) { for(i = 0; (path[i] != '\0') && (path[i] != '\n'); i++); path[i] = '\0'; load_cert = path; } if (NULL != fgets(path, 1024, ifd)) { for(i = 0; (path[i] != '\0') && (path[i] != '\n'); i++); path[i] = '\0'; load_key = path; } fclose(ifd); } // we have now // 1) checked or created the config dirs. // 2) loaded the config_init file - if possible. return; } int create_configinit() { // Check for config file. std::string initfile = config_basedir + dirSeperator; initfile += config_init_file; // open and read in the lines. FILE *ifd = fopen(initfile.c_str(), "w"); /* char path[1024]; int i; */ if (ifd != NULL) { fprintf(ifd, "%s\n", load_cert.c_str()); fprintf(ifd, "%s\n", load_key.c_str()); fclose(ifd); std::cerr << "Creating Init File: " << initfile << std::endl; std::cerr << "\tLoad Cert: " << load_cert << std::endl; std::cerr << "\tLoad Key: " << load_key << std::endl; return 1; } std::cerr << "Failed To Create Init File: " << initfile << std::endl; return -1; } int check_create_directory(std::string dir) { struct stat buf; int val = stat(dir.c_str(), &buf); if (val == -1) { // directory don't exist. create. /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS // UNIX if (-1 == mkdir(dir.c_str(), 0777)) #else // WIN if (-1 == mkdir(dir.c_str())) #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ { std::cerr << "check_create_directory() Fatal Error --"; std::cerr <value()); std::string s("LOCL USR"); inp -> value(""); //fserv -> chatmsg(m,s); fserv -> ownchatmsg(m); std::cerr << "Wish we could talk!" << std::endl; return; } void alert_okay_msg(Fl_Return_Button*, void*) { ui -> alert_window -> hide(); std::cerr << "Alert Okay" << std::endl; return; } void alert_cancel_msg(Fl_Button*, void*) { ui -> alert_window -> hide(); std::cerr << "Abort Cancel" << std::endl; return; } void file_result_select(Fl_File_Browser*, void*) { std::cerr << "FL_FILE_BROWSER::file_select!!!!" << std::endl; } void file_download(Fl_Button*, void*) { std::cerr << "FL_BUTTON::file_download!!!!" << std::endl; fserv->dirlist_download(); } void file_recommend(Fl_Button*, void*) { std::cerr << "FL_BUTTON::file_recommend!!!!" << std::endl; fserv->dirlist_recommend(); } void file_requestdir(std::string person, std::string dir) { std::cerr << "Request Dir Listing:" << person << ":" << dir << std::endl; fserv->load_dir(person, dir); } /* New Callback Fns for Channels *****************************/ /* add to channel broadcast (from dir_listing) */ void file_channel_broadcast(Fl_Button*, void*) { std::cerr << "file_channel_broadcast()"; std::cerr << std::endl; return; } /* add to channel broadcast (from search) */ void search_channel_broadcast(Fl_Button*, void*) { std::cerr << "search_channel_broadcast()"; std::cerr << std::endl; return; } /* callback for own channel select */ void channel_own_list_select(Fl_Browser*, void*) { std::cerr << "channel_own_list_select()"; std::cerr << std::endl; return; } /* callback for others channel select */ void channel_list_select(Fl_Funky_Browser*, void*) { std::cerr << "channel_list_select()"; std::cerr << std::endl; return; } /* callback for channel file listing select */ void channel_file_list_select(Fl_Funky_Browser*, void*) { std::cerr << "channel_file_list_select()"; std::cerr << std::endl; return; } /* button press to create channel */ void channel_create(Fl_Button*, void*) { std::cerr << "channel_create()"; std::cerr << std::endl; ui->channel_create_window->show(); return; } /* button press to delete selected own channel */ void channel_delete(Fl_Button*, void*) { std::cerr << "channel_delete()"; std::cerr << std::endl; return; } /* open/close chat window */ void chat_open_callback(Fl_Button*, void*) { std::cerr << "chat_open()"; std::cerr << std::endl; if (ui->chatter_window->shown()) { ui->chatter_window->hide(); } else { ui->chatter_window->show(); } return; } void channel_show_callback(Fl_Button*, void*) { std::cerr << "channel_show_callback()"; std::cerr << std::endl; ui->channel_details_window->show(); return; } void channel_delete_callback(Fl_Button*, void*) { std::cerr << "channel_delete_callback()"; std::cerr << std::endl; return; } void chan_createmsg_list_select(Fl_Funky_Browser*, void*) { std::cerr << "chan_createmsg_list_select()"; std::cerr << std::endl; return; } void chan_createmsg_sendmsg_callback(Fl_Button*, void*) { std::cerr << "chan_createmsg_sendmsg_callback()"; std::cerr << std::endl; return; } void chan_createmsg_postpone_callback(Fl_Button*, void*) { std::cerr << "chan_createmsg_postpone_callback()"; std::cerr << std::endl; ui->channel_create_window->hide(); return; } void chan_createmsg_cancel_callback(Fl_Button*, void*) { std::cerr << "chan_createmsg_cancel_callback()"; std::cerr << std::endl; ui->channel_create_window->hide(); return; } void chan_createmsg_remove_callback(Fl_Button*, void*) { std::cerr << "chan_createmsg_remove_callback()"; std::cerr << std::endl; return; } void chan_createmsg_newname_callback(Fl_Input*, void*) { std::cerr << "chan_createmsg_newname_callback()"; std::cerr << std::endl; return; } void chan_createmsg_newname_button_callback(Fl_Round_Button*, void*) { std::cerr << "chan_createmsg_newname_button_callback()"; std::cerr << std::endl; return; } void chan_createmsg_title_button_callback(Fl_Round_Button*, void*) { std::cerr << "chan_createmsg_button_callback()"; std::cerr << std::endl; return; } void chan_msgdetails_list_select(Fl_Funky_Browser*, void*) { std::cerr << "chan_msgdetails_list_select()"; std::cerr << std::endl; return; } void chan_msgdetails_download_callback(Fl_Button*, void*) { std::cerr << "chan_msgdetails_download_callback()"; std::cerr << std::endl; return; } void chan_msgdetails_subscribe_callback(Fl_Button*, void*) { std::cerr << "chan_msgdetails_subscribe_callback()"; std::cerr << std::endl; return; } void chan_msgdetails_close_callback(Fl_Button*, void*) { std::cerr << "chan_msgdetails_close_callback()"; std::cerr << std::endl; ui->channel_details_window->hide(); return; }