mirror of
https://github.com/moparisthebest/hexchat
synced 2024-11-14 05:15:05 -05:00
1417 lines
26 KiB
C
1417 lines
26 KiB
C
/* X-Chat
|
|
* Copyright (C) 1998 Peter Zelezny.
|
|
*
|
|
* This program 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.
|
|
*
|
|
* This program 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 this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#ifndef WIN32
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include "hexchat.h"
|
|
#include <glib.h>
|
|
|
|
#include "cfgfiles.h"
|
|
#include "fe.h"
|
|
#include "server.h"
|
|
#include "text.h"
|
|
#include "util.h" /* token_foreach */
|
|
#include "hexchatc.h"
|
|
|
|
#include "servlist.h"
|
|
|
|
|
|
struct defaultserver
|
|
{
|
|
char *network;
|
|
char *host;
|
|
char *channel;
|
|
char *charset;
|
|
};
|
|
|
|
static const struct defaultserver def[] =
|
|
{
|
|
{"2600net", 0},
|
|
{0, "irc.2600.net"},
|
|
|
|
/* {"7-indonesia", 0},
|
|
{0, "irc.7-indonesia.org"},*/
|
|
|
|
{"AccessIRC", 0},
|
|
{0, "irc.accessirc.net"},
|
|
{0, "eu.accessirc.net"},
|
|
|
|
{"AfterNET", 0},
|
|
{0, "irc.afternet.org"},
|
|
{0, "us.afternet.org"},
|
|
{0, "eu.afternet.org"},
|
|
|
|
{"Aitvaras", 0},
|
|
#ifdef USE_IPV6
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc6.ktu.lt/+7668"},
|
|
#endif
|
|
{0, "irc6.ktu.lt/7666"},
|
|
#endif
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.data.lt/+6668"},
|
|
{0, "irc-ssl.omnitel.net/+6668"},
|
|
{0, "irc-ssl.le.lt/+9999"},
|
|
#endif
|
|
{0, "irc.data.lt"},
|
|
{0, "irc.omnitel.net"},
|
|
{0, "irc.ktu.lt"},
|
|
{0, "irc.le.lt"},
|
|
{0, "irc.takas.lt"},
|
|
{0, "irc.5ci.net"},
|
|
{0, "irc.kis.lt"},
|
|
|
|
{"AlphaChat", 0},
|
|
{0, "irc.alphachat.net"},
|
|
{0, "na.alphachat.net"},
|
|
{0, "eu.alphachat.net"},
|
|
{0, "au.alphachat.net"},
|
|
{0, "za.alphachat.net"},
|
|
|
|
/* {"AmigaNet", 0},
|
|
{0, "irc.amiganet.org"},
|
|
{0, "us.amiganet.org"},
|
|
{0, "uk.amiganet.org"},
|
|
{0, "no.amiganet.org"},
|
|
{0, "au.amiganet.org"},*/
|
|
|
|
{"ARCNet", 0},
|
|
{0, "se1.arcnet.vapor.com"},
|
|
{0, "us1.arcnet.vapor.com"},
|
|
{0, "us2.arcnet.vapor.com"},
|
|
{0, "us3.arcnet.vapor.com"},
|
|
{0, "ca1.arcnet.vapor.com"},
|
|
{0, "de1.arcnet.vapor.com"},
|
|
{0, "de3.arcnet.vapor.com"},
|
|
{0, "ch1.arcnet.vapor.com"},
|
|
{0, "be1.arcnet.vapor.com"},
|
|
{0, "nl3.arcnet.vapor.com"},
|
|
{0, "uk1.arcnet.vapor.com"},
|
|
{0, "uk2.arcnet.vapor.com"},
|
|
/* {0, "uk3.arcnet.vapor.com"},*/
|
|
{0, "fr1.arcnet.vapor.com"},
|
|
|
|
/* {"AstroLink", 0},
|
|
{0, "irc.astrolink.org"},*/
|
|
|
|
{"AustNet", 0},
|
|
{0, "au.austnet.org"},
|
|
{0, "us.austnet.org"},
|
|
{0, "ca.austnet.org"},
|
|
|
|
/* {"AxeNet", 0},
|
|
{0, "irc.axenet.org"},
|
|
{0, "angel.axenet.org"},
|
|
{0, "energy.axenet.org"},
|
|
{0, "python.axenet.org"},*/
|
|
|
|
{"AzzurraNet", 0},
|
|
{0, "irc.azzurra.org"},
|
|
{0, "crypto.azzurra.org"},
|
|
|
|
{"Beirut", 0},
|
|
{0, "irc.beirut.com"},
|
|
|
|
{"Chat4all", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.chat4all.org/+7001"},
|
|
#endif
|
|
{0, "irc.chat4all.org"},
|
|
|
|
{"ChattingAway", 0},
|
|
{0, "irc.chattingaway.com"},
|
|
|
|
{"ChatJunkies", 0, "#xchat"},
|
|
{0, "irc.chatjunkies.org"},
|
|
{0, "nl.chatjunkies.org"},
|
|
|
|
{"ChatNet", 0},
|
|
{0, "US.ChatNet.Org"},
|
|
{0, "EU.ChatNet.Org"},
|
|
|
|
/* {"ChatSociety", 0},
|
|
{0, "us.chatsociety.net"},
|
|
{0, "eu.chatsociety.net"},*/
|
|
|
|
{"ChatSpike", 0},
|
|
{0, "irc.chatspike.net"},
|
|
|
|
/* {"CoolChat", 0},
|
|
{0, "irc.coolchat.net"},
|
|
{0, "unix.coolchat.net"},
|
|
{0, "toronto.coolchat.net"},*/
|
|
|
|
{"Criten", 0},
|
|
{0, "irc.criten.net"},
|
|
{0, "irc.eu.criten.net"},
|
|
|
|
{"DALnet", 0},
|
|
{0, "irc.dal.net"},
|
|
{0, "irc.eu.dal.net"},
|
|
|
|
{"Dark-Tou-Net", 0},
|
|
{0, "irc.d-t-net.de"},
|
|
{0, "bw.d-t-net.de"},
|
|
{0, "nc.d-t-net.de"},
|
|
{0, "wakka.d-t-net.de"},
|
|
|
|
{"DarkMyst", 0},
|
|
{0, "irc.darkmyst.org"},
|
|
|
|
{"DeepIRC", 0},
|
|
{0, "irc.deepirc.net"},
|
|
|
|
{"DeltaAnime", 0},
|
|
{0, "irc.deltaanime.net"},
|
|
|
|
{"EFnet", 0},
|
|
{0, "irc.blackened.com"},
|
|
{0, "irc.Prison.NET"},
|
|
{0, "irc.Qeast.net"},
|
|
{0, "irc.efnet.pl"},
|
|
{0, "efnet.demon.co.uk"},
|
|
/* {0, "irc.lagged.org"},*/
|
|
{0, "irc.lightning.net"},
|
|
{0, "irc.mindspring.com"},
|
|
{0, "irc.easynews.com"},
|
|
{0, "irc.servercentral.net"},
|
|
|
|
{"EnterTheGame", 0},
|
|
{0, "IRC.EnterTheGame.Com"},
|
|
|
|
{"EntropyNet", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.entropynet.net/+6697"},
|
|
#endif
|
|
{0, "irc.entropynet.net"},
|
|
#ifdef USE_IPV6
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc6.entropynet.net/+6697"},
|
|
#endif
|
|
{0, "irc6.entropynet.net"},
|
|
#endif
|
|
|
|
{"EsperNet", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.esper.net/+6697"},
|
|
#endif
|
|
{0, "irc.esper.net"},
|
|
|
|
{"EUIrc", 0},
|
|
{0, "irc.euirc.net"},
|
|
{0, "irc.ham.de.euirc.net"},
|
|
{0, "irc.ber.de.euirc.net"},
|
|
{0, "irc.ffm.de.euirc.net"},
|
|
{0, "irc.bre.de.euirc.net"},
|
|
{0, "irc.hes.de.euirc.net"},
|
|
{0, "irc.vie.at.euirc.net"},
|
|
{0, "irc.inn.at.euirc.net"},
|
|
{0, "irc.bas.ch.euirc.net"},
|
|
|
|
{"EuropNet", 0},
|
|
{0, "irc.europnet.org"},
|
|
|
|
/* {"EU-IRC", 0},
|
|
{0, "irc.eu-irc.net"},*/
|
|
|
|
{"FDFNet", 0},
|
|
{0, "irc.fdfnet.net"},
|
|
{0, "irc.eu.fdfnet.net"},
|
|
|
|
{"FEFNet", 0},
|
|
{0, "irc.fef.net"},
|
|
{0, "irc.ggn.net"},
|
|
{0, "irc.vendetta.com"},
|
|
|
|
{"freenode", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.freenode.net/+6697"},
|
|
#endif
|
|
{0, "irc.freenode.net"},
|
|
|
|
/* {"Freeworld", 0},
|
|
{0, "kabel.freeworld.nu"},
|
|
{0, "irc.freeworld.nu"},*/
|
|
|
|
{"Fusion Latina", 0},
|
|
{0, "irc.fusionlatina.org/2012"},
|
|
|
|
{"GalaxyNet", 0},
|
|
{0, "irc.galaxynet.org"},
|
|
/* {0, "sprynet.us.galaxynet.org"},
|
|
{0, "atlanta.ga.us.galaxynet.org"},*/
|
|
|
|
{"GameSurge", 0},
|
|
{0, "irc.gamesurge.net"},
|
|
|
|
/* {"GamesNET", 0},
|
|
{0, "irc.gamesnet.net"},
|
|
{0, "irc.us.gamesnet.net"},
|
|
{0, "east.us.gamesnet.net"},
|
|
{0, "west.us.gamesnet.net"},
|
|
{0, "irc.ca.gamesnet.net"},
|
|
{0, "irc.eu.gamesnet.net"},*/
|
|
|
|
{"GeekShed", 0},
|
|
{0, "irc.geekshed.net"},
|
|
|
|
{"German-Elite", 0},
|
|
{0, "dominion.german-elite.net"},
|
|
{0, "komatu.german-elite.net"},
|
|
/* {0, "liberty.german-elite.net"},*/
|
|
|
|
{"GIMPNet", 0},
|
|
{0, "irc.gimp.org"},
|
|
{0, "irc.gnome.org"},
|
|
/* {0, "irc.au.gimp.org"},*/
|
|
{0, "irc.us.gimp.org"},
|
|
|
|
/* {"HabberNet", 0},
|
|
{0, "irc.habber.net"},*/
|
|
|
|
{"Hashmark", 0},
|
|
{0, "irc.hashmark.net"},
|
|
|
|
{"IdleMonkeys", 0},
|
|
{0, "irc.idlemonkeys.net"},
|
|
|
|
{"IndirectIRC", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.indirectirc.com/+6697"},
|
|
#endif
|
|
{0, "irc.indirectirc.com"},
|
|
|
|
/* {"Infinity-IRC", 0},
|
|
{0, "Atlanta.GA.US.Infinity-IRC.Org"},
|
|
{0, "Babylon.NY.US.Infinity-IRC.Org"},
|
|
{0, "Sunshine.Ca.US.Infinity-IRC.Org"},
|
|
{0, "IRC.Infinity-IRC.Org"},*/
|
|
|
|
{"IRCHighWay", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.irchighway.net/+9999"},
|
|
#endif
|
|
{0, "irc.irchighway.net"},
|
|
|
|
{"IrcLink", 0},
|
|
{0, "irc.irclink.net"},
|
|
{0, "Alesund.no.eu.irclink.net"},
|
|
{0, "Oslo.no.eu.irclink.net"},
|
|
{0, "frogn.no.eu.irclink.net"},
|
|
{0, "tonsberg.no.eu.irclink.net"},
|
|
|
|
{"IRCNet", 0},
|
|
{0, "irc.stealth.net/6668"},
|
|
{0, "ircnet.demon.co.uk"},
|
|
/* {0, "ircnet.hinet.hr"},*/
|
|
{0, "irc.datacomm.ch"},
|
|
/* {0, "ircnet.kaptech.fr"},
|
|
{0, "ircnet.easynet.co.uk"},*/
|
|
{0, "random.ircd.de"},
|
|
{0, "ircnet.netvision.net.il"},
|
|
/* {0, "irc.seed.net.tw"},*/
|
|
{0, "irc.cs.hut.fi"},
|
|
|
|
{"Irctoo.net", 0},
|
|
{0, "irc.irctoo.net"},
|
|
|
|
{"IronDust", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.irondust.net/+6697"},
|
|
#endif
|
|
{0, "irc.irondust.net"},
|
|
|
|
{"iZ-smart.net", 0},
|
|
{0, "irc.iZ-smart.net/6666"},
|
|
{0, "irc.iZ-smart.net/6667"},
|
|
{0, "irc.iZ-smart.net/6668"},
|
|
|
|
{"Krstarica", 0},
|
|
{0, "irc.krstarica.com"},
|
|
|
|
{"Librenet", 0},
|
|
{0, "irc.librenet.net"},
|
|
{0, "ielf.fr.librenet.net"},
|
|
|
|
#ifdef USE_OPENSSL
|
|
{"LinkNet", 0},
|
|
{0, "irc.link-net.org/+7000"},
|
|
{0, "as.link-net.org/+7000"},
|
|
{0, "eu.link-net.org/+7000"},
|
|
{0, "us.link-net.org/+7000"},
|
|
#ifdef USE_IPV6
|
|
{0, "irc6.link-net.org/+7000"},
|
|
#endif
|
|
/* {0, "irc.no.link-net.org"},
|
|
{0, "irc.gamesden.net.au"},
|
|
{0, "irc.bahnhof.se"},
|
|
{0, "irc.kinexuseurope.co.uk"},
|
|
{0, "irc.gamiix.com"},*/
|
|
#endif
|
|
|
|
/* {"Majistic", 0},
|
|
{0, "irc.majistic.net"},*/
|
|
|
|
{"MindForge", 0},
|
|
{0, "irc.mindforge.org"},
|
|
|
|
/* {"MintIRC", 0},
|
|
{0, "irc.mintirc.net"},*/
|
|
|
|
{"MIXXnet", 0},
|
|
{0, "irc.mixxnet.net"},
|
|
|
|
{"Moznet", 0},
|
|
{0, "irc.mozilla.org"},
|
|
|
|
{"NeverNET", 0},
|
|
{0, "irc.nevernet.net"},
|
|
{0, "imagine.nevernet.net"},
|
|
{0, "dimension.nevernet.net"},
|
|
{0, "universe.nevernet.net"},
|
|
{0, "wayland.nevernet.net"},
|
|
{0, "forte.nevernet.net"},
|
|
|
|
{"NixHelpNet", 0},
|
|
{0, "irc.nixhelp.org"},
|
|
{0, "us.nixhelp.org"},
|
|
{0, "uk.nixhelp.org"},
|
|
{0, "uk2.nixhelp.org"},
|
|
{0, "uk3.nixhelp.org"},
|
|
{0, "nl.nixhelp.org"},
|
|
{0, "ca.ld.nixhelp.org"},
|
|
{0, "us.co.nixhelp.org"},
|
|
{0, "us.ca.nixhelp.org"},
|
|
{0, "us.pa.nixhelp.org"},
|
|
|
|
/* {"NullusNet", 0},
|
|
{0, "irc.nullus.net"},*/
|
|
|
|
{"Oceanius", 0},
|
|
{0, "irc.oceanius.com"},
|
|
|
|
{"OFTC", 0},
|
|
{0, "irc.oftc.net"},
|
|
|
|
{"OtherNet", 0},
|
|
{0, "irc.othernet.org"},
|
|
|
|
{"OzNet", 0},
|
|
{0, "irc.oz.org"},
|
|
|
|
{"PIRC.PL", 0},
|
|
{0, "irc.pirc.pl"},
|
|
|
|
{"PTNet.org", 0},
|
|
{0, "irc.PTNet.org"},
|
|
{0, "world.PTnet.org"},
|
|
{0, "netvisao.PTnet.org"},
|
|
{0, "uevora.PTnet.org"},
|
|
{0, "vianetworks.PTnet.org"},
|
|
{0, "uc.PTnet.org"},
|
|
{0, "nfsi.ptnet.org"},
|
|
{0, "fctunl.ptnet.org"},
|
|
|
|
{"QuakeNet", 0},
|
|
{0, "irc.quakenet.org"},
|
|
{0, "irc.se.quakenet.org"},
|
|
{0, "irc.dk.quakenet.org"},
|
|
{0, "irc.no.quakenet.org"},
|
|
{0, "irc.fi.quakenet.org"},
|
|
{0, "irc.be.quakenet.org"},
|
|
{0, "irc.uk.quakenet.org"},
|
|
{0, "irc.de.quakenet.org"},
|
|
{0, "irc.it.quakenet.org"},
|
|
|
|
/* {"RebelChat", 0},
|
|
{0, "irc.rebelchat.org"},*/
|
|
|
|
/* {"Recycled-IRC", 0},
|
|
{0, "irc.recycled-irc.org"},
|
|
{0, "vermin.recycled-irc.org"},
|
|
{0, "waste.recycled-irc.org"},
|
|
{0, "lumber.recycled-irc.org"},
|
|
{0, "trash.recycled-irc.org"},
|
|
{0, "unwashed.recycled-irc.org"},
|
|
{0, "garbage.recycled-irc.org"},
|
|
{0, "dustbin.recycled-irc.org"},*/
|
|
|
|
/* {"RizeNET", 0},
|
|
{0, "irc.rizenet.org"},
|
|
{0, "omega.rizenet.org"},
|
|
{0, "evelance.rizenet.org"},
|
|
{0, "lisa.rizenet.org"},
|
|
{0, "scott.rizenet.org"},*/
|
|
|
|
{"Rizon", 0},
|
|
{0, "irc.rizon.net"},
|
|
|
|
{"RusNet", 0, 0, "KOI8-R (Cyrillic)"},
|
|
{0, "irc.tomsk.net"},
|
|
{0, "irc.rinet.ru"},
|
|
{0, "irc.run.net"},
|
|
{0, "irc.ru"},
|
|
{0, "irc.lucky.net"},
|
|
|
|
{"SceneNet", 0},
|
|
{0, "irc.scene.org"},
|
|
{0, "irc.eu.scene.org"},
|
|
{0, "irc.us.scene.org"},
|
|
|
|
{"SeilEn.de", 0},
|
|
{0, "irc.seilen.de"},
|
|
|
|
{"SlashNET", 0},
|
|
{0, "irc.slashnet.org"},
|
|
{0, "area51.slashnet.org"},
|
|
{0, "moo.slashnet.org"},
|
|
{0, "radon.slashnet.org"},
|
|
|
|
{"Snoonet", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.snoonet.com/+6697"},
|
|
#endif
|
|
{0, "irc.snoonet.com/6667"},
|
|
|
|
{"Sohbet.Net", 0},
|
|
{0, "irc.sohbet.net"},
|
|
|
|
{"SolidIRC", 0},
|
|
{0, "irc.solidirc.com"},
|
|
|
|
{"SorceryNet", 0},
|
|
{0, "irc.sorcery.net/9000"},
|
|
{0, "irc.us.sorcery.net/9000"},
|
|
{0, "irc.eu.sorcery.net/9000"},
|
|
|
|
/* {"Spidernet", 0},
|
|
{0, "us.spidernet.org"},
|
|
{0, "eu.spidernet.org"},
|
|
{0, "irc.spidernet.org"},*/
|
|
|
|
{"StarChat", 0},
|
|
{0, "irc.starchat.net"},
|
|
{0, "gainesville.starchat.net"},
|
|
{0, "freebsd.starchat.net"},
|
|
{0, "sunset.starchat.net"},
|
|
{0, "revenge.starchat.net"},
|
|
{0, "tahoma.starchat.net"},
|
|
{0, "neo.starchat.net"},
|
|
|
|
{"SwiftIRC", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.swiftirc.net/+6697"},
|
|
#endif
|
|
{0, "irc.swiftirc.net/6667"},
|
|
|
|
/* {"TNI3", 0},
|
|
{0, "irc.tni3.com"},*/
|
|
|
|
{"TURLINet", 0},
|
|
{0, "irc.turli.net"},
|
|
{0, "irc.servx.ru"},
|
|
{0, "irc.gavnos.ru"},
|
|
|
|
{"UnderNet", 0},
|
|
{0, "us.undernet.org"},
|
|
{0, "eu.undernet.org"},
|
|
|
|
{"UniBG", 0},
|
|
{0, "irc.lirex.com"},
|
|
{0, "irc.naturella.com"},
|
|
{0, "irc.spnet.net"},
|
|
{0, "irc.techno-link.com"},
|
|
{0, "irc.telecoms.bg"},
|
|
{0, "irc.tu-varna.edu"},
|
|
|
|
{"Whiffle", 0},
|
|
{0, "irc.whiffle.org"},
|
|
|
|
{"Worldnet", 0},
|
|
{0, "irc.worldnet.net"},
|
|
{0, "irc.fr.worldnet.net"},
|
|
|
|
{"Windfyre", 0},
|
|
#ifdef USE_OPENSSL
|
|
{0, "irc.windfyre.net/+6697"},
|
|
#endif
|
|
{0, "irc.windfyre.net"},
|
|
|
|
/* {"Xentonix.net", 0},
|
|
{0, "irc.xentonix.net"},*/
|
|
|
|
/* {"XWorld", 0},
|
|
{0, "Buffalo.NY.US.XWorld.org"},
|
|
{0, "Minneapolis.MN.US.Xworld.Org"},
|
|
{0, "Rochester.NY.US.XWorld.org"},
|
|
{0, "Bayern.DE.EU.XWorld.Org"},
|
|
{0, "Chicago.IL.US.XWorld.Org"},*/
|
|
|
|
{0,0}
|
|
};
|
|
|
|
GSList *network_list = 0;
|
|
|
|
|
|
void
|
|
servlist_connect (session *sess, ircnet *net, gboolean join)
|
|
{
|
|
ircserver *ircserv;
|
|
GSList *list;
|
|
char *port;
|
|
server *serv;
|
|
|
|
if (!sess)
|
|
sess = new_ircwindow (NULL, NULL, SESS_SERVER, TRUE);
|
|
|
|
serv = sess->server;
|
|
|
|
/* connect to the currently selected Server-row */
|
|
list = g_slist_nth (net->servlist, net->selected);
|
|
if (!list)
|
|
list = net->servlist;
|
|
if (!list)
|
|
return;
|
|
ircserv = list->data;
|
|
|
|
/* incase a protocol switch is added to the servlist gui */
|
|
server_fill_her_up (sess->server);
|
|
|
|
if (join)
|
|
{
|
|
sess->willjoinchannel[0] = 0;
|
|
|
|
if (net->autojoin)
|
|
{
|
|
if (serv->autojoin)
|
|
free (serv->autojoin);
|
|
serv->autojoin = strdup (net->autojoin);
|
|
}
|
|
}
|
|
|
|
serv->password[0] = 0;
|
|
serv->sasluser[0] = 0;
|
|
serv->saslpassword[0] = 0;
|
|
|
|
if (net->pass)
|
|
{
|
|
safe_strcpy (serv->password, net->pass, sizeof (serv->password));
|
|
}
|
|
|
|
if (net->flags & FLAG_USE_GLOBAL)
|
|
{
|
|
strcpy (serv->sasluser, prefs.hex_irc_user_name);
|
|
}
|
|
else if (net->user != NULL)
|
|
{
|
|
safe_strcpy (serv->sasluser, net->user, sizeof (serv->sasluser));
|
|
}
|
|
|
|
if (net->saslpass)
|
|
{
|
|
safe_strcpy (serv->saslpassword, net->saslpass, sizeof (serv->saslpassword));
|
|
}
|
|
|
|
if (net->flags & FLAG_USE_GLOBAL)
|
|
{
|
|
strcpy (serv->nick, prefs.hex_irc_nick1);
|
|
}
|
|
else
|
|
{
|
|
if (net->nick)
|
|
strcpy (serv->nick, net->nick);
|
|
}
|
|
|
|
serv->dont_use_proxy = (net->flags & FLAG_USE_PROXY) ? FALSE : TRUE;
|
|
|
|
#ifdef USE_OPENSSL
|
|
serv->use_ssl = (net->flags & FLAG_USE_SSL) ? TRUE : FALSE;
|
|
serv->accept_invalid_cert =
|
|
(net->flags & FLAG_ALLOW_INVALID) ? TRUE : FALSE;
|
|
#endif
|
|
|
|
serv->network = net;
|
|
|
|
port = strrchr (ircserv->hostname, '/');
|
|
if (port)
|
|
{
|
|
*port = 0;
|
|
|
|
/* support "+port" to indicate SSL (like mIRC does) */
|
|
if (port[1] == '+')
|
|
{
|
|
#ifdef USE_OPENSSL
|
|
serv->use_ssl = TRUE;
|
|
#endif
|
|
serv->connect (serv, ircserv->hostname, atoi (port + 2), FALSE);
|
|
} else
|
|
{
|
|
serv->connect (serv, ircserv->hostname, atoi (port + 1), FALSE);
|
|
}
|
|
|
|
*port = '/';
|
|
} else
|
|
serv->connect (serv, ircserv->hostname, -1, FALSE);
|
|
|
|
server_set_encoding (serv, net->encoding);
|
|
}
|
|
|
|
int
|
|
servlist_connect_by_netname (session *sess, char *network, gboolean join)
|
|
{
|
|
ircnet *net;
|
|
GSList *list = network_list;
|
|
|
|
while (list)
|
|
{
|
|
net = list->data;
|
|
|
|
if (g_ascii_strcasecmp (net->name, network) == 0)
|
|
{
|
|
servlist_connect (sess, net, join);
|
|
return 1;
|
|
}
|
|
|
|
list = list->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
servlist_have_auto (void)
|
|
{
|
|
GSList *list = network_list;
|
|
ircnet *net;
|
|
|
|
while (list)
|
|
{
|
|
net = list->data;
|
|
|
|
if (net->flags & FLAG_AUTO_CONNECT)
|
|
return 1;
|
|
|
|
list = list->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
servlist_auto_connect (session *sess)
|
|
{
|
|
GSList *list = network_list;
|
|
ircnet *net;
|
|
int ret = 0;
|
|
|
|
while (list)
|
|
{
|
|
net = list->data;
|
|
|
|
if (net->flags & FLAG_AUTO_CONNECT)
|
|
{
|
|
servlist_connect (sess, net, TRUE);
|
|
ret = 1;
|
|
}
|
|
|
|
list = list->next;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static gint
|
|
servlist_cycle_cb (server *serv)
|
|
{
|
|
if (serv->network)
|
|
{
|
|
PrintTextf (serv->server_session,
|
|
_("Cycling to next server in %s...\n"), ((ircnet *)serv->network)->name);
|
|
servlist_connect (serv->server_session, serv->network, TRUE);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
servlist_cycle (server *serv)
|
|
{
|
|
ircnet *net;
|
|
int max, del;
|
|
|
|
net = serv->network;
|
|
if (net)
|
|
{
|
|
max = g_slist_length (net->servlist);
|
|
if (max > 0)
|
|
{
|
|
/* try the next server, if that option is on */
|
|
if (net->flags & FLAG_CYCLE)
|
|
{
|
|
net->selected++;
|
|
if (net->selected >= max)
|
|
net->selected = 0;
|
|
}
|
|
|
|
del = prefs.hex_net_reconnect_delay * 1000;
|
|
if (del < 1000)
|
|
del = 500; /* so it doesn't block the gui */
|
|
|
|
if (del)
|
|
serv->recondelay_tag = fe_timeout_add (del, servlist_cycle_cb, serv);
|
|
else
|
|
servlist_connect (serv->server_session, net, TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
ircserver *
|
|
servlist_server_find (ircnet *net, char *name, int *pos)
|
|
{
|
|
GSList *list = net->servlist;
|
|
ircserver *serv;
|
|
int i = 0;
|
|
|
|
while (list)
|
|
{
|
|
serv = list->data;
|
|
if (strcmp (serv->hostname, name) == 0)
|
|
{
|
|
if (pos)
|
|
*pos = i;
|
|
return serv;
|
|
}
|
|
i++;
|
|
list = list->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* find a network (e.g. (ircnet *) to "FreeNode") from a hostname
|
|
(e.g. "irc.eu.freenode.net") */
|
|
|
|
ircnet *
|
|
servlist_net_find_from_server (char *server_name)
|
|
{
|
|
GSList *list = network_list;
|
|
GSList *slist;
|
|
ircnet *net;
|
|
ircserver *serv;
|
|
|
|
while (list)
|
|
{
|
|
net = list->data;
|
|
|
|
slist = net->servlist;
|
|
while (slist)
|
|
{
|
|
serv = slist->data;
|
|
if (g_ascii_strcasecmp (serv->hostname, server_name) == 0)
|
|
return net;
|
|
slist = slist->next;
|
|
}
|
|
|
|
list = list->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
ircnet *
|
|
servlist_net_find (char *name, int *pos, int (*cmpfunc) (const char *, const char *))
|
|
{
|
|
GSList *list = network_list;
|
|
ircnet *net;
|
|
int i = 0;
|
|
|
|
while (list)
|
|
{
|
|
net = list->data;
|
|
if (cmpfunc (net->name, name) == 0)
|
|
{
|
|
if (pos)
|
|
*pos = i;
|
|
return net;
|
|
}
|
|
i++;
|
|
list = list->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
ircserver *
|
|
servlist_server_add (ircnet *net, char *name)
|
|
{
|
|
ircserver *serv;
|
|
|
|
serv = malloc (sizeof (ircserver));
|
|
memset (serv, 0, sizeof (ircserver));
|
|
serv->hostname = strdup (name);
|
|
|
|
net->servlist = g_slist_append (net->servlist, serv);
|
|
|
|
return serv;
|
|
}
|
|
|
|
void
|
|
servlist_server_remove (ircnet *net, ircserver *serv)
|
|
{
|
|
free (serv->hostname);
|
|
free (serv);
|
|
net->servlist = g_slist_remove (net->servlist, serv);
|
|
}
|
|
|
|
static void
|
|
servlist_server_remove_all (ircnet *net)
|
|
{
|
|
ircserver *serv;
|
|
|
|
while (net->servlist)
|
|
{
|
|
serv = net->servlist->data;
|
|
servlist_server_remove (net, serv);
|
|
}
|
|
}
|
|
|
|
static void
|
|
free_and_clear (char *str)
|
|
{
|
|
if (str)
|
|
{
|
|
char *orig = str;
|
|
while (*str)
|
|
*str++ = 0;
|
|
free (orig);
|
|
}
|
|
}
|
|
|
|
/* executed on exit: Clear any password strings */
|
|
|
|
void
|
|
servlist_cleanup (void)
|
|
{
|
|
GSList *list;
|
|
ircnet *net;
|
|
|
|
for (list = network_list; list; list = list->next)
|
|
{
|
|
net = list->data;
|
|
free_and_clear (net->pass);
|
|
free_and_clear (net->saslpass);
|
|
free_and_clear (net->nickserv);
|
|
}
|
|
}
|
|
|
|
void
|
|
servlist_net_remove (ircnet *net)
|
|
{
|
|
GSList *list;
|
|
server *serv;
|
|
|
|
servlist_server_remove_all (net);
|
|
network_list = g_slist_remove (network_list, net);
|
|
|
|
if (net->nick)
|
|
free (net->nick);
|
|
if (net->nick2)
|
|
free (net->nick2);
|
|
if (net->user)
|
|
free (net->user);
|
|
if (net->real)
|
|
free (net->real);
|
|
free_and_clear (net->pass);
|
|
free_and_clear (net->saslpass);
|
|
if (net->autojoin)
|
|
free (net->autojoin);
|
|
if (net->command)
|
|
free (net->command);
|
|
free_and_clear (net->nickserv);
|
|
if (net->comment)
|
|
free (net->comment);
|
|
if (net->encoding)
|
|
free (net->encoding);
|
|
free (net->name);
|
|
free (net);
|
|
|
|
/* for safety */
|
|
list = serv_list;
|
|
while (list)
|
|
{
|
|
serv = list->data;
|
|
if (serv->network == net)
|
|
serv->network = NULL;
|
|
list = list->next;
|
|
}
|
|
}
|
|
|
|
ircnet *
|
|
servlist_net_add (char *name, char *comment, int prepend)
|
|
{
|
|
ircnet *net;
|
|
|
|
net = malloc (sizeof (ircnet));
|
|
memset (net, 0, sizeof (ircnet));
|
|
net->name = strdup (name);
|
|
/* net->comment = strdup (comment);*/
|
|
net->flags = FLAG_CYCLE | FLAG_USE_GLOBAL | FLAG_USE_PROXY;
|
|
|
|
if (prepend)
|
|
network_list = g_slist_prepend (network_list, net);
|
|
else
|
|
network_list = g_slist_append (network_list, net);
|
|
|
|
return net;
|
|
}
|
|
|
|
static void
|
|
servlist_load_defaults (void)
|
|
{
|
|
int i = 0, j = 0;
|
|
ircnet *net = NULL;
|
|
guint def_hash = g_str_hash ("freenode");
|
|
|
|
while (1)
|
|
{
|
|
if (def[i].network)
|
|
{
|
|
net = servlist_net_add (def[i].network, def[i].host, FALSE);
|
|
net->encoding = strdup (IRC_DEFAULT_CHARSET);
|
|
if (def[i].channel)
|
|
{
|
|
net->autojoin = strdup (def[i].channel);
|
|
}
|
|
if (def[i].charset)
|
|
{
|
|
free (net->encoding);
|
|
net->encoding = strdup (def[i].charset);
|
|
}
|
|
if (g_str_hash (def[i].network) == def_hash)
|
|
{
|
|
prefs.hex_gui_slist_select = j;
|
|
}
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
servlist_server_add (net, def[i].host);
|
|
if (!def[i+1].host && !def[i+1].network)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
static int
|
|
servlist_load (void)
|
|
{
|
|
FILE *fp;
|
|
char buf[2048];
|
|
int len;
|
|
char *tmp;
|
|
ircnet *net = NULL;
|
|
|
|
fp = hexchat_fopen_file ("servlist_.conf", "r", 0);
|
|
if (!fp)
|
|
return FALSE;
|
|
|
|
while (fgets (buf, sizeof (buf) - 2, fp))
|
|
{
|
|
len = strlen (buf);
|
|
buf[len] = 0;
|
|
buf[len-1] = 0; /* remove the trailing \n */
|
|
if (net)
|
|
{
|
|
switch (buf[0])
|
|
{
|
|
case 'I':
|
|
net->nick = strdup (buf + 2);
|
|
break;
|
|
case 'i':
|
|
net->nick2 = strdup (buf + 2);
|
|
break;
|
|
case 'U':
|
|
net->user = strdup (buf + 2);
|
|
break;
|
|
case 'R':
|
|
net->real = strdup (buf + 2);
|
|
break;
|
|
case 'P':
|
|
net->pass = strdup (buf + 2);
|
|
break;
|
|
case 'A':
|
|
net->saslpass = strdup (buf + 2);
|
|
break;
|
|
case 'J':
|
|
net->autojoin = strdup (buf + 2);
|
|
break;
|
|
case 'C':
|
|
if (net->command)
|
|
{
|
|
/* concat extra commands with a \n separator */
|
|
tmp = net->command;
|
|
net->command = malloc (strlen (tmp) + strlen (buf + 2) + 2);
|
|
strcpy (net->command, tmp);
|
|
strcat (net->command, "\n");
|
|
strcat (net->command, buf + 2);
|
|
free (tmp);
|
|
} else
|
|
net->command = strdup (buf + 2);
|
|
break;
|
|
case 'F':
|
|
net->flags = atoi (buf + 2);
|
|
break;
|
|
case 'D':
|
|
net->selected = atoi (buf + 2);
|
|
break;
|
|
case 'E':
|
|
net->encoding = strdup (buf + 2);
|
|
break;
|
|
case 'S': /* new server/hostname for this network */
|
|
servlist_server_add (net, buf + 2);
|
|
break;
|
|
case 'B':
|
|
net->nickserv = strdup (buf + 2);
|
|
break;
|
|
}
|
|
}
|
|
if (buf[0] == 'N')
|
|
net = servlist_net_add (buf + 2, /* comment */ NULL, FALSE);
|
|
}
|
|
fclose (fp);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
servlist_init (void)
|
|
{
|
|
if (!network_list)
|
|
if (!servlist_load ())
|
|
servlist_load_defaults ();
|
|
}
|
|
|
|
/* check if a charset is known by Iconv */
|
|
int
|
|
servlist_check_encoding (char *charset)
|
|
{
|
|
GIConv gic;
|
|
char *c;
|
|
|
|
c = strchr (charset, ' ');
|
|
if (c)
|
|
c[0] = 0;
|
|
|
|
if (!g_ascii_strcasecmp (charset, "IRC")) /* special case */
|
|
{
|
|
if (c)
|
|
c[0] = ' ';
|
|
return TRUE;
|
|
}
|
|
|
|
gic = g_iconv_open (charset, "UTF-8");
|
|
|
|
if (c)
|
|
c[0] = ' ';
|
|
|
|
if (gic != (GIConv)-1)
|
|
{
|
|
g_iconv_close (gic);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int
|
|
servlist_write_ccmd (char *str, void *fp)
|
|
{
|
|
return fprintf (fp, "C=%s\n", (str[0] == '/') ? str + 1 : str);
|
|
}
|
|
|
|
|
|
int
|
|
servlist_save (void)
|
|
{
|
|
FILE *fp;
|
|
char *buf;
|
|
ircnet *net;
|
|
ircserver *serv;
|
|
GSList *list;
|
|
GSList *hlist;
|
|
#ifndef WIN32
|
|
int first = FALSE;
|
|
|
|
buf = g_strdup_printf ("%s/servlist_.conf", get_xdir ());
|
|
if (g_access (buf, F_OK) != 0)
|
|
first = TRUE;
|
|
#endif
|
|
|
|
fp = hexchat_fopen_file ("servlist_.conf", "w", 0);
|
|
if (!fp)
|
|
{
|
|
#ifndef WIN32
|
|
g_free (buf);
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
#ifndef WIN32
|
|
if (first)
|
|
g_chmod (buf, 0600);
|
|
|
|
g_free (buf);
|
|
#endif
|
|
fprintf (fp, "v=" PACKAGE_VERSION "\n\n");
|
|
|
|
list = network_list;
|
|
while (list)
|
|
{
|
|
net = list->data;
|
|
|
|
fprintf (fp, "N=%s\n", net->name);
|
|
if (net->nick)
|
|
fprintf (fp, "I=%s\n", net->nick);
|
|
if (net->nick2)
|
|
fprintf (fp, "i=%s\n", net->nick2);
|
|
if (net->user)
|
|
fprintf (fp, "U=%s\n", net->user);
|
|
if (net->real)
|
|
fprintf (fp, "R=%s\n", net->real);
|
|
if (net->pass)
|
|
fprintf (fp, "P=%s\n", net->pass);
|
|
if (net->saslpass)
|
|
fprintf (fp, "A=%s\n", net->saslpass);
|
|
if (net->autojoin)
|
|
fprintf (fp, "J=%s\n", net->autojoin);
|
|
if (net->nickserv)
|
|
fprintf (fp, "B=%s\n", net->nickserv);
|
|
if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") &&
|
|
g_ascii_strcasecmp (net->encoding, "System default"))
|
|
{
|
|
fprintf (fp, "E=%s\n", net->encoding);
|
|
if (!servlist_check_encoding (net->encoding))
|
|
{
|
|
buf = g_strdup_printf (_("Warning: \"%s\" character set is unknown. No conversion will be applied for network %s."),
|
|
net->encoding, net->name);
|
|
fe_message (buf, FE_MSG_WARN);
|
|
g_free (buf);
|
|
}
|
|
}
|
|
|
|
if (net->command)
|
|
token_foreach (net->command, '\n', servlist_write_ccmd, fp);
|
|
|
|
fprintf (fp, "F=%d\nD=%d\n", net->flags, net->selected);
|
|
|
|
hlist = net->servlist;
|
|
while (hlist)
|
|
{
|
|
serv = hlist->data;
|
|
fprintf (fp, "S=%s\n", serv->hostname);
|
|
hlist = hlist->next;
|
|
}
|
|
|
|
if (fprintf (fp, "\n") < 1)
|
|
{
|
|
fclose (fp);
|
|
return FALSE;
|
|
}
|
|
|
|
list = list->next;
|
|
}
|
|
|
|
fclose (fp);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
joinlist_free1 (GSList *list)
|
|
{
|
|
GSList *head = list;
|
|
|
|
for (; list; list = list->next)
|
|
g_free (list->data);
|
|
g_slist_free (head);
|
|
}
|
|
|
|
void
|
|
joinlist_free (GSList *channels, GSList *keys)
|
|
{
|
|
joinlist_free1 (channels);
|
|
joinlist_free1 (keys);
|
|
}
|
|
|
|
gboolean
|
|
joinlist_is_in_list (server *serv, char *channel)
|
|
{
|
|
GSList *channels, *keys;
|
|
GSList *list;
|
|
|
|
if (!serv->network || !((ircnet *)serv->network)->autojoin)
|
|
return FALSE;
|
|
|
|
joinlist_split (((ircnet *)serv->network)->autojoin, &channels, &keys);
|
|
|
|
for (list = channels; list; list = list->next)
|
|
{
|
|
if (serv->p_cmp (list->data, channel) == 0)
|
|
return TRUE;
|
|
}
|
|
|
|
joinlist_free (channels, keys);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
gchar *
|
|
joinlist_merge (GSList *channels, GSList *keys)
|
|
{
|
|
GString *out = g_string_new (NULL);
|
|
GSList *list;
|
|
int i, j;
|
|
|
|
for (; channels; channels = channels->next)
|
|
{
|
|
g_string_append (out, channels->data);
|
|
|
|
if (channels->next)
|
|
g_string_append_c (out, ',');
|
|
}
|
|
|
|
/* count number of REAL keys */
|
|
for (i = 0, list = keys; list; list = list->next)
|
|
if (list->data)
|
|
i++;
|
|
|
|
if (i > 0)
|
|
{
|
|
g_string_append_c (out, ' ');
|
|
|
|
for (j = 0; keys; keys = keys->next)
|
|
{
|
|
if (keys->data)
|
|
{
|
|
g_string_append (out, keys->data);
|
|
j++;
|
|
if (j == i)
|
|
break;
|
|
}
|
|
|
|
if (keys->next)
|
|
g_string_append_c (out, ',');
|
|
}
|
|
}
|
|
|
|
return g_string_free (out, FALSE);
|
|
}
|
|
|
|
void
|
|
joinlist_split (char *autojoin, GSList **channels, GSList **keys)
|
|
{
|
|
char *parta, *partb;
|
|
char *chan, *key;
|
|
int len;
|
|
|
|
*channels = NULL;
|
|
*keys = NULL;
|
|
|
|
/* after the first space, the keys begin */
|
|
parta = autojoin;
|
|
partb = strchr (autojoin, ' ');
|
|
if (partb)
|
|
partb++;
|
|
|
|
while (1)
|
|
{
|
|
chan = parta;
|
|
key = partb;
|
|
|
|
if (1)
|
|
{
|
|
while (parta[0] != 0 && parta[0] != ',' && parta[0] != ' ')
|
|
{
|
|
parta++;
|
|
}
|
|
}
|
|
|
|
if (partb)
|
|
{
|
|
while (partb[0] != 0 && partb[0] != ',' && partb[0] != ' ')
|
|
{
|
|
partb++;
|
|
}
|
|
}
|
|
|
|
len = parta - chan;
|
|
if (len < 1)
|
|
break;
|
|
*channels = g_slist_append (*channels, g_strndup (chan, len));
|
|
|
|
len = partb - key;
|
|
*keys = g_slist_append (*keys, len ? g_strndup (key, len) : NULL);
|
|
|
|
if (parta[0] == ' ' || parta[0] == 0)
|
|
break;
|
|
parta++;
|
|
|
|
if (partb)
|
|
{
|
|
if (partb[0] == 0 || partb[0] == ' ')
|
|
partb = NULL; /* no more keys, but maybe more channels? */
|
|
else
|
|
partb++;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
GSList *lista, *listb;
|
|
int i;
|
|
|
|
printf("-----\n");
|
|
i = 0;
|
|
lista = *channels;
|
|
listb = *keys;
|
|
while (lista)
|
|
{
|
|
printf("%d. |%s| |%s|\n", i, lista->data, listb->data);
|
|
i++;
|
|
lista = lista->next;
|
|
listb = listb->next;
|
|
}
|
|
printf("-----\n\n");
|
|
#endif
|
|
}
|
|
|
|
|