diff options
Diffstat (limited to 'src/common')
35 files changed, 1540 insertions, 206 deletions
diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c index 83f50e37..111234e9 100644 --- a/src/common/cfgfiles.c +++ b/src/common/cfgfiles.c @@ -17,7 +17,6 @@ */ #include <fcntl.h> -#include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -31,12 +30,15 @@ #include "text.h" #include "xchatc.h" -#ifdef WIN32 -#define XCHAT_DIR "X-Chat 2" -#else +#ifndef WIN32 +#include <unistd.h> #define XCHAT_DIR ".xchat2" #endif + #define DEF_FONT "Monospace 9" +#ifdef WIN32 +#define DEF_FONT_ALTER "Arial Unicode MS,Lucida Sans Unicode" +#endif void list_addentry (GSList ** list, char *cmd, char *name) @@ -82,11 +84,11 @@ list_load_from_data (GSList ** list, char *ibuf, int size) { if (*buf != '#') { - if (!strncasecmp (buf, "NAME ", 5)) + if (!g_ascii_strncasecmp (buf, "NAME ", 5)) { safe_strcpy (name, buf + 5, sizeof (name)); } - else if (!strncasecmp (buf, "CMD ", 4)) + else if (!g_ascii_strncasecmp (buf, "CMD ", 4)) { safe_strcpy (cmd, buf + 4, sizeof (cmd)); if (*name) @@ -152,7 +154,7 @@ list_delentry (GSList ** list, char *name) while (alist) { pop = (struct popup *) alist->data; - if (!strcasecmp (name, pop->name)) + if (!g_ascii_strcasecmp (name, pop->name)) { *list = g_slist_remove (*list, pop); free (pop); @@ -166,9 +168,13 @@ list_delentry (GSList ** list, char *name) char * cfg_get_str (char *cfg, char *var, char *dest, int dest_len) { + char buffer[128]; /* should be plenty for a variable name */ + + sprintf (buffer, "%s ", var); /* add one space, this way it works against var - var2 checks too */ + while (1) { - if (!strncasecmp (var, cfg, strlen (var))) + if (!g_ascii_strncasecmp (buffer, cfg, strlen (var) + 1)) { char *value, t; cfg += strlen (var); @@ -308,12 +314,19 @@ get_xdir_fs (void) { if (!xdir_fs) { - char out[256]; + if (portable_mode ()) + { + xdir_fs = ".\\config"; + } + else + { + char out[256]; - if (!get_reg_str ("Software\\Microsoft\\Windows\\CurrentVersion\\" - "Explorer\\Shell Folders", "AppData", out, sizeof (out))) - return "./config"; - xdir_fs = g_strdup_printf ("%s\\" XCHAT_DIR, out); + if (!get_reg_str ("Software\\Microsoft\\Windows\\CurrentVersion\\" + "Explorer\\Shell Folders", "AppData", out, sizeof (out))) + return "./config"; + xdir_fs = g_strdup_printf ("%s\\" "X-Chat 2", out); + } } return xdir_fs; } @@ -393,7 +406,9 @@ const struct prefs vars[] = { {"dcc_blocksize", P_OFFINT (dcc_blocksize), TYPE_INT}, {"dcc_completed_dir", P_OFFSET (dcc_completed_dir), TYPE_STR}, {"dcc_dir", P_OFFSET (dccdir), TYPE_STR}, +#ifndef WIN32 {"dcc_fast_send", P_OFFINT (fastdccsend), TYPE_BOOL}, +#endif {"dcc_global_max_get_cps", P_OFFINT (dcc_global_max_get_cps), TYPE_INT}, {"dcc_global_max_send_cps", P_OFFINT (dcc_global_max_send_cps), TYPE_INT}, {"dcc_ip", P_OFFSET (dcc_ip_str), TYPE_STR}, @@ -429,9 +444,14 @@ const struct prefs vars[] = { {"gui_input_style", P_OFFINT (style_inputbox), TYPE_BOOL}, {"gui_join_dialog", P_OFFINT (gui_join_dialog), TYPE_BOOL}, {"gui_lagometer", P_OFFINT (lagometer), TYPE_INT}, + {"gui_license", P_OFFSET (gui_license), TYPE_STR}, {"gui_mode_buttons", P_OFFINT (chanmodebuttons), TYPE_BOOL}, +#ifdef WIN32 + {"gui_one_instance", P_OFFINT (gui_one_instance), TYPE_BOOL}, +#endif {"gui_pane_left_size", P_OFFINT (gui_pane_left_size), TYPE_INT}, {"gui_pane_right_size", P_OFFINT (gui_pane_right_size), TYPE_INT}, + {"gui_pane_right_size_min", P_OFFINT (gui_pane_right_size_min), TYPE_INT}, {"gui_quit_dialog", P_OFFINT (gui_quit_dialog), TYPE_BOOL}, {"gui_slist_fav", P_OFFINT (slist_fav), TYPE_INT}, {"gui_slist_select", P_OFFINT (slist_select), TYPE_INT}, @@ -536,6 +556,9 @@ const struct prefs vars[] = { {"tab_chans", P_OFFINT (tabchannels), TYPE_BOOL}, {"tab_dialogs", P_OFFINT (privmsgtab), TYPE_BOOL}, +#ifdef WIN32 + {"tab_icons", P_OFFINT (tab_icons), TYPE_BOOL}, +#endif {"tab_layout", P_OFFINT (tab_layout), TYPE_INT}, {"tab_new_to_front", P_OFFINT (newtabstofront), TYPE_INT}, {"tab_notices", P_OFFINT (notices_tabs), TYPE_BOOL}, @@ -546,16 +569,35 @@ const struct prefs vars[] = { {"tab_sort", P_OFFINT (tab_sort), TYPE_BOOL}, {"tab_trunc", P_OFFINT (truncchans), TYPE_INT}, {"tab_utils", P_OFFINT (windows_as_tabs), TYPE_BOOL}, +#ifdef WIN32 + {"tab_xp", P_OFFINT (tab_xp), TYPE_BOOL}, +#endif + {"text_auto_copy_color", P_OFFINT (autocopy_color), TYPE_BOOL}, + {"text_auto_copy_stamp", P_OFFINT (autocopy_stamp), TYPE_BOOL}, + {"text_auto_copy_text", P_OFFINT (autocopy_text), TYPE_BOOL}, {"text_background", P_OFFSET (background), TYPE_STR}, {"text_color_nicks", P_OFFINT (colorednicks), TYPE_BOOL}, +#ifdef WIN32 + {"text_emoticons", P_OFFINT (emoticons), TYPE_BOOL}, +#endif {"text_font", P_OFFSET (font_normal), TYPE_STR}, +#ifdef WIN32 + {"text_font_main", P_OFFSET (font_main), TYPE_STR}, + {"text_font_alternative", P_OFFSET (font_alternative), TYPE_STR}, +#endif {"text_indent", P_OFFINT (indent_nicks), TYPE_BOOL}, {"text_max_indent", P_OFFINT (max_auto_indent), TYPE_INT}, {"text_max_lines", P_OFFINT (max_lines), TYPE_INT}, {"text_replay", P_OFFINT (text_replay), TYPE_BOOL}, + {"text_search_case_match", P_OFFINT (text_search_case_match), TYPE_BOOL}, + {"text_search_backward", P_OFFINT (text_search_backward), TYPE_BOOL}, + {"text_search_highlight_all", P_OFFINT (text_search_highlight_all), TYPE_BOOL}, + {"text_search_follow", P_OFFINT (text_search_follow), TYPE_BOOL}, + {"text_search_regexp", P_OFFINT (text_search_regexp), TYPE_BOOL}, {"text_show_marker", P_OFFINT (show_marker), TYPE_BOOL}, {"text_show_sep", P_OFFINT (show_separator), TYPE_BOOL}, + {"text_spell_langs", P_OFFSET (spell_langs), TYPE_STR}, {"text_stripcolor", P_OFFINT (stripcolor), TYPE_BOOL}, {"text_thin_sep", P_OFFINT (thin_separator), TYPE_BOOL}, {"text_tint_blue", P_OFFINT (tint_blue), TYPE_INT}, @@ -601,9 +643,11 @@ load_config (void) if (!username) username = "root"; - realname = g_get_real_name (); + /* We hid Real name from the Network List, so don't use the user's name unnoticeably */ + /* realname = g_get_real_name (); if ((realname && realname[0] == 0) || !realname) - realname = username; + realname = username; */ + realname = "realname"; username = convert_with_fallback (username, "username"); realname = convert_with_fallback (realname, "realname"); @@ -626,13 +670,16 @@ load_config (void) prefs.indent_nicks = 1; prefs.thin_separator = 1; prefs._tabs_position = 2; /* 2 = left */ +#ifndef WIN32 prefs.fastdccsend = 1; +#endif prefs.wordwrap = 1; prefs.autosave = 1; prefs.autodialog = 1; prefs.gui_input_spell = 1; prefs.autoreconnect = 1; prefs.recon_delay = 10; + prefs.autocopy_text = 1; prefs.text_replay = 1; prefs.tabchannels = 1; prefs.tab_layout = 2; /* 0=Tabs 1=Reserved 2=Tree */ @@ -676,6 +723,7 @@ load_config (void) prefs.gui_tray = 1; prefs.gui_pane_left_size = 100; prefs.gui_pane_right_size = 100; + prefs.gui_pane_right_size_min = 80; prefs.mainwindow_save = 1; prefs.bantype = 2; prefs.input_balloon_time = 20; @@ -684,9 +732,12 @@ load_config (void) prefs.autodccsend = 2; /* browse mode */ prefs.url_grabber = 1; prefs.url_grabber_limit = 0; /* 0 means unlimited for backcompat */ + prefs.text_search_follow = 1; #ifdef WIN32 prefs.identd = 1; #endif + strcpy (prefs.gui_license, ""); + strcpy (prefs.spell_langs, g_getenv ("LC_ALL") ? g_getenv ("LC_ALL") : "en_US"); strcpy (prefs.stamp_format, "[%H:%M] "); strcpy (prefs.timestamp_log_format, "%b %d %H:%M:%S "); strcpy (prefs.logmask, "%n-%c.log"); @@ -719,6 +770,10 @@ load_config (void) strcpy (prefs.quitreason, _("Leaving")); strcpy (prefs.partreason, prefs.quitreason); strcpy (prefs.font_normal, DEF_FONT); +#ifdef WIN32 + strcpy (prefs.font_main, DEF_FONT); + strcpy (prefs.font_alternative, DEF_FONT_ALTER); +#endif strcpy (prefs.dnsprogram, "host"); strcpy (prefs.irc_no_hilight, "NickServ,ChanServ"); @@ -945,7 +1000,7 @@ cfg_get_bool (char *var) do { - if (!strcasecmp (var, vars[i].name)) + if (!g_ascii_strcasecmp (var, vars[i].name)) { return *((int *) &prefs + vars[i].offset); } @@ -968,27 +1023,27 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) int idx = 2; char *var, *val; - if (strcasecmp (word[2], "-e") == 0) + if (g_ascii_strcasecmp (word[2], "-e") == 0) { idx++; erase = TRUE; } /* turn a bit OFF */ - if (strcasecmp (word[idx], "-off") == 0) + if (g_ascii_strcasecmp (word[idx], "-off") == 0) { idx++; off = TRUE; } /* turn a bit ON */ - if (strcasecmp (word[idx], "-or") == 0 || strcasecmp (word[idx], "-on") == 0) + if (g_ascii_strcasecmp (word[idx], "-or") == 0 || g_ascii_strcasecmp (word[idx], "-on") == 0) { idx++; or = TRUE; } - if (strcasecmp (word[idx], "-quiet") == 0) + if (g_ascii_strcasecmp (word[idx], "-quiet") == 0) { idx++; quiet = TRUE; @@ -1014,7 +1069,7 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (wild) found = !match (var, vars[i].name); else - found = strcasecmp (var, vars[i].name); + found = g_ascii_strcasecmp (var, vars[i].name); if (found == 0) { @@ -1043,9 +1098,9 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) *((int *) &prefs + vars[i].offset) = 1; else *((int *) &prefs + vars[i].offset) = 0; - if (!strcasecmp (val, "YES") || !strcasecmp (val, "ON")) + if (!g_ascii_strcasecmp (val, "YES") || !g_ascii_strcasecmp (val, "ON")) *((int *) &prefs + vars[i].offset) = 1; - if (!strcasecmp (val, "NO") || !strcasecmp (val, "OFF")) + if (!g_ascii_strcasecmp (val, "NO") || !g_ascii_strcasecmp (val, "OFF")) *((int *) &prefs + vars[i].offset) = 0; } else { @@ -1071,7 +1126,13 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) while (vars[i].name); if (!finds && !quiet) + { PrintText (sess, "No such variable.\n"); + } + else if (prefs.autosave && !save_config ()) + { + PrintText (sess, "Error saving changes to disk.\n"); + } return TRUE; } diff --git a/src/common/chanopt.c b/src/common/chanopt.c index a4fd8faa..198ebe6c 100644 --- a/src/common/chanopt.c +++ b/src/common/chanopt.c @@ -3,12 +3,15 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #include "xchat.h" #include "cfgfiles.h" @@ -81,9 +84,9 @@ chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[]) if (word[offset][0]) { - if (!strcasecmp (word[offset], "ON")) + if (!g_ascii_strcasecmp (word[offset], "ON")) newval = 1; - else if (!strcasecmp (word[offset], "OFF")) + else if (!g_ascii_strcasecmp (word[offset], "OFF")) newval = 0; else if (word[offset][0] == 'u') newval = SET_DEFAULT; @@ -183,8 +186,8 @@ chanopt_find (char *network, char *channel, gboolean add_new) for (list = chanopt_list; list; list = list->next) { co = list->data; - if (!strcasecmp (co->channel, channel) && - !strcasecmp (co->network, network)) + if (!g_ascii_strcasecmp (co->channel, channel) && + !g_ascii_strcasecmp (co->network, network)) return co; } diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj new file mode 100644 index 00000000..4e95c929 --- /dev/null +++ b/src/common/common.vcxproj @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\config.h" /> + <ClInclude Include="cfgfiles.h" /> + <ClInclude Include="chanopt.h" /> + <ClInclude Include="ctcp.h" /> + <ClInclude Include="dcc.h" /> + <ClInclude Include="fe.h" /> + <ClInclude Include="history.h" /> + <ClInclude Include="identd.h" /> + <ClInclude Include="ignore.h" /> + <ClInclude Include="inbound.h" /> + <ClInclude Include="inet.h" /> + <ClInclude Include="modes.h" /> + <ClInclude Include="msproxy.h" /> + <ClInclude Include="network.h" /> + <ClInclude Include="notify.h" /> + <ClInclude Include="outbound.h" /> + <ClInclude Include="plugin-timer.h" /> + <ClInclude Include="plugin.h" /> + <ClInclude Include="proto-irc.h" /> + <ClInclude Include="server.h" /> + <ClInclude Include="servlist.h" /> + <ClInclude Include="ssl.h" /> + <ClInclude Include="text.h" /> + <ClInclude Include="textenums.h" /> + <ClInclude Include="textevents.h" /> + <ClInclude Include="thread.h" /> + <ClInclude Include="tree.h" /> + <ClInclude Include="url.h" /> + <ClInclude Include="userlist.h" /> + <ClInclude Include="util.h" /> + <ClInclude Include="xchat-plugin.h" /> + <ClInclude Include="xchat.h" /> + <ClInclude Include="xchatc.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="cfgfiles.c" /> + <ClCompile Include="chanopt.c" /> + <ClCompile Include="ctcp.c" /> + <ClCompile Include="dcc.c" /> + <ClCompile Include="history.c" /> + <ClCompile Include="identd.c" /> + <ClCompile Include="ignore.c" /> + <ClCompile Include="inbound.c" /> + <ClCompile Include="modes.c" /> + <ClCompile Include="msproxy.c" /> + <ClCompile Include="network.c" /> + <ClCompile Include="notify.c" /> + <ClCompile Include="outbound.c" /> + <ClCompile Include="plugin-timer.c" /> + <ClCompile Include="plugin.c" /> + <ClCompile Include="proto-irc.c" /> + <ClCompile Include="server.c" /> + <ClCompile Include="servlist.c" /> + <ClCompile Include="ssl.c" /> + <ClCompile Include="text.c" /> + <ClCompile Include="thread.c" /> + <ClCompile Include="tree.c" /> + <ClCompile Include="url.c" /> + <ClCompile Include="userlist.c" /> + <ClCompile Include="util.c" /> + <ClCompile Include="xchat.c" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{87554B59-006C-4D94-9714-897B27067BA3}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>common</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>WDK7</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>WDK7</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\xchat.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\xchat.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)build\$(PlatformName)\bin</OutDir> + <IntDir>$(SolutionDir)build\$(PlatformName)\obj\$(ProjectName)</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)build\$(PlatformName)\bin</OutDir> + <IntDir>$(SolutionDir)build\$(PlatformName)\obj\$(ProjectName)</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level1</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level1</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;_WIN64;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters new file mode 100644 index 00000000..afb66e63 --- /dev/null +++ b/src/common/common.vcxproj.filters @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="cfgfiles.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="chanopt.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ctcp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dcc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="fe.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="history.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="identd.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ignore.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="inbound.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="inet.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="modes.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="msproxy.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="network.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="notify.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="outbound.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="plugin.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="plugin-timer.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="proto-irc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="server.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="servlist.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="text.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="textenums.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="textevents.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="thread.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="tree.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="url.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="userlist.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="xchat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="xchatc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="xchat-plugin.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="cfgfiles.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="chanopt.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ctcp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dcc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="history.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="identd.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ignore.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="inbound.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="modes.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="msproxy.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="network.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="notify.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="outbound.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="plugin.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="plugin-timer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="proto-irc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="server.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="servlist.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="text.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="thread.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="tree.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="url.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="userlist.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="util.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="xchat.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/common/common.vcxproj.user b/src/common/common.vcxproj.user new file mode 100644 index 00000000..695b5c78 --- /dev/null +++ b/src/common/common.vcxproj.user @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +</Project> \ No newline at end of file diff --git a/src/common/ctcp.c b/src/common/ctcp.c index 574cda79..36952db7 100644 --- a/src/common/ctcp.c +++ b/src/common/ctcp.c @@ -18,9 +18,12 @@ #include <stdio.h> #include <string.h> -#include <unistd.h> #include <stdlib.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #include "xchat.h" #include "cfgfiles.h" #include "util.h" @@ -70,7 +73,7 @@ ctcp_check (session *sess, char *nick, char *word[], char *word_eol[], while (list) { pop = (struct popup *) list->data; - if (!strcasecmp (ctcp, pop->name)) + if (!g_ascii_strcasecmp (ctcp, pop->name)) { ctcp_reply (sess, nick, word, word_eol, pop->cmd); ret = 1; @@ -94,7 +97,7 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, ctcp_offset = 3; /* consider DCC to be different from other CTCPs */ - if (!strncasecmp (msg, "DCC", 3)) + if (!g_ascii_strncasecmp (msg, "DCC", 3)) { /* but still let CTCP replies override it */ if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) @@ -107,7 +110,7 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, /* consider ACTION to be different from other CTCPs. Check ignore as if it was a PRIV/CHAN. */ - if (!strncasecmp (msg, "ACTION ", 7)) + if (!g_ascii_strncasecmp (msg, "ACTION ", 7)) { if (is_channel (serv, to)) { @@ -132,16 +135,21 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, if (ignore_check (word[1], IG_CTCP)) return; - if (!strcasecmp (msg, "VERSION") && !prefs.hidever) + if (!g_ascii_strcasecmp (msg, "VERSION") && !prefs.hidever) { - snprintf (outbuf, sizeof (outbuf), "VERSION xchat "PACKAGE_VERSION" %s", +#ifdef WIN32 + snprintf (outbuf, sizeof (outbuf), "VERSION XChat-WDK "PACKAGE_VERSION" [x%d] / %s", + get_cpu_arch (), get_cpu_str ()); +#else + snprintf (outbuf, sizeof (outbuf), "VERSION XChat-WDK "PACKAGE_VERSION" %s", get_cpu_str ()); +#endif serv->p_nctcp (serv, nick, outbuf); } if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) { - if (!strncasecmp (msg, "SOUND", 5)) + if (!g_ascii_strncasecmp (msg, "SOUND", 5)) { po = strchr (word[5], '\001'); if (po) diff --git a/src/common/dcc.c b/src/common/dcc.c index 8f289342..4c8724d9 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -31,7 +31,6 @@ #include <time.h> #include <errno.h> #include <sys/stat.h> -#include <unistd.h> #include <fcntl.h> #define WANTSOCKET @@ -41,6 +40,8 @@ #ifdef WIN32 #include <windows.h> +#else +#include <unistd.h> #endif #include "xchat.h" @@ -57,6 +58,9 @@ #ifdef USE_DCC64 #define BIG_STR_TO_INT(x) strtoull(x,NULL,10) +#ifdef WIN32 +#define stat _stat64 +#endif #else #define BIG_STR_TO_INT(x) strtoul(x,NULL,10) #endif @@ -568,7 +572,7 @@ dcc_chat_line (struct DCC *dcc, char *line) url_check_line (line, len); - if (line[0] == 1 && !strncasecmp (line + 1, "ACTION", 6)) + if (line[0] == 1 && !g_ascii_strncasecmp (line + 1, "ACTION", 6)) { po = strchr (line + 8, '\001'); if (po) @@ -1936,9 +1940,9 @@ find_dcc (char *nick, char *file, int type) { if (!file[0]) return dcc; - if (!strcasecmp (file, file_part (dcc->file))) + if (!g_ascii_strcasecmp (file, file_part (dcc->file))) return dcc; - if (!strcasecmp (file, dcc->file)) + if (!g_ascii_strcasecmp (file, dcc->file)) return dcc; } } @@ -1984,7 +1988,7 @@ is_same_file (struct DCC *dcc, struct DCC *new_dcc) /* now handle case-insensitive Filesystems: HFS+, FAT */ #ifdef WIN32 -#warning no win32 implementation - behaviour may be unreliable + /* warning no win32 implementation - behaviour may be unreliable */ #else /* this fstat() shouldn't really fail */ if ((dcc->fp == -1 ? stat (dcc->destfile_fs, &st_a) : fstat (dcc->fp, &st_a)) == -1) @@ -2402,7 +2406,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], DCC_SIZE size; int psend = 0; - if (!strcasecmp (type, "CHAT")) + if (!g_ascii_strcasecmp (type, "CHAT")) { port = atoi (word[8]); addr = strtoul (word[7], NULL, 10); @@ -2449,7 +2453,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], return; } - if (!strcasecmp (type, "Resume")) + if (!g_ascii_strcasecmp (type, "Resume")) { port = atoi (word[7]); @@ -2493,7 +2497,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], } return; } - if (!strcasecmp (type, "Accept")) + if (!g_ascii_strcasecmp (type, "Accept")) { port = atoi (word[7]); dcc = find_dcc_from_port (port, TYPE_RECV); @@ -2503,7 +2507,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], } return; } - if (!strcasecmp (type, "SEND")) + if (!g_ascii_strcasecmp (type, "SEND")) { char *file = file_part (word[6]); diff --git a/src/common/identd.c b/src/common/identd.c index 919282ea..430c7e8f 100644 --- a/src/common/identd.c +++ b/src/common/identd.c @@ -1,8 +1,13 @@ /* simple identd server for xchat under win32 */ +#include "inet.h" +#include "xchat.h" +#include "xchatc.h" static int identd_is_running = FALSE; - +#ifdef USE_IPV6 +static int identd_ipv6_is_running = FALSE; +#endif static int identd (char *username) @@ -75,11 +80,102 @@ identd (char *username) return 0; } -static void +#ifdef USE_IPV6 +static int +identd_ipv6 (char *username) +{ + int sok, read_sok, len; + char *p; + char buf[256]; + char outbuf[256]; + char ipv6buf[60]; + DWORD ipv6buflen = sizeof (ipv6buf); + struct sockaddr_in6 addr; + + sok = socket (AF_INET6, SOCK_STREAM, 0); + + if (sok == INVALID_SOCKET) + { + free (username); + return 0; + } + + len = 1; + setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len)); + + memset (&addr, 0, sizeof (addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons (113); + + if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR) + { + closesocket (sok); + free (username); + return 0; + } + + if (listen (sok, 1) == SOCKET_ERROR) + { + closesocket (sok); + free (username); + return 0; + } + + len = sizeof (addr); + read_sok = accept (sok, (struct sockaddr *) &addr, &len); + closesocket (sok); + + if (read_sok == INVALID_SOCKET) + { + free (username); + return 0; + } + + identd_ipv6_is_running = FALSE; + + if (WSAAddressToString ((struct sockaddr *) &addr, sizeof (addr), NULL, &ipv6buf, &ipv6buflen) == SOCKET_ERROR) + { + snprintf (ipv6buf, sizeof (ipv6buf) - 1, "[SOCKET ERROR: 0x%X]", WSAGetLastError ()); + } + + snprintf (outbuf, sizeof (outbuf), "%%\tServicing ident request from %s\n", ipv6buf); + PrintText (current_sess, outbuf); + + recv (read_sok, buf, sizeof (buf) - 1, 0); + buf[sizeof (buf) - 1] = 0; /* ensure null termination */ + + p = strchr (buf, ','); + + if (p) + { + snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n", atoi (buf), atoi (p + 1), username); + outbuf[sizeof (outbuf) - 1] = 0; /* ensure null termination */ + send (read_sok, outbuf, strlen (outbuf), 0); + } + + sleep (1); + closesocket (read_sok); + free (username); + + return 0; +} +#endif + +void identd_start (char *username) { DWORD tid; +#ifdef USE_IPV6 + DWORD tidv6; + if (identd_ipv6_is_running == FALSE) + { + identd_ipv6_is_running = TRUE; + CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd_ipv6, + strdup (username), 0, &tidv6)); + } +#endif + if (identd_is_running == FALSE) { identd_is_running = TRUE; diff --git a/src/common/identd.h b/src/common/identd.h new file mode 100644 index 00000000..636f9641 --- /dev/null +++ b/src/common/identd.h @@ -0,0 +1 @@ +void identd_start (char *username); diff --git a/src/common/ignore.c b/src/common/ignore.c index c3544f30..0ed23daa 100644 --- a/src/common/ignore.c +++ b/src/common/ignore.c @@ -19,11 +19,14 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #include "xchat.h" #include "ignore.h" #include "cfgfiles.h" diff --git a/src/common/inbound.c b/src/common/inbound.c index 719bbe60..89899655 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -21,9 +21,12 @@ #include <stdlib.h> #include <stdio.h> #include <sys/types.h> -#include <unistd.h> #include <time.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #define WANTARPA #define WANTDNS #include "inet.h" @@ -883,7 +886,7 @@ inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id) if (msg[0] == '[' && (!serv->have_idmsg || id)) { /* guess where chanserv meant to post this -sigh- */ - if (!strcasecmp (nick, "ChanServ") && !find_dialog (serv, nick)) + if (!g_ascii_strcasecmp (nick, "ChanServ") && !find_dialog (serv, nick)) { char *dest = strdup (msg + 1); char *end = strchr (dest, ']'); diff --git a/src/common/inet.h b/src/common/inet.h index b420c9c6..8995569c 100644 --- a/src/common/inet.h +++ b/src/common/inet.h @@ -21,12 +21,12 @@ #else +#include "../../config.h" #ifdef USE_IPV6 #include <winsock2.h> #include <ws2tcpip.h> -#include <tpipv6.h> #else -#include <winsock.h> +#include <winsock2.h> #endif #define set_blocking(sok) { \ diff --git a/src/common/makefile.mak b/src/common/makefile.mak new file mode 100644 index 00000000..d6df2608 --- /dev/null +++ b/src/common/makefile.mak @@ -0,0 +1,45 @@ +include "..\makeinc.mak" + +COMMON_OBJECTS = \ +cfgfiles.obj \ +chanopt.obj \ +ctcp.obj \ +dcc.obj \ +dirent-win32.obj \ +history.obj \ +identd.obj \ +ignore.obj \ +inbound.obj \ +modes.obj \ +network.obj \ +notify.obj \ +outbound.obj \ +plugin.obj \ +plugin-timer.obj \ +proto-irc.obj \ +server.obj \ +servlist.obj \ +ssl.obj \ +text.obj \ +thread.obj \ +tree.obj \ +url.obj \ +userlist.obj \ +util.obj \ +xchat.obj + +all: $(COMMON_OBJECTS) xchatcommon.lib dirent-win32.lib + +xchatcommon.lib: $(COMMON_OBJECTS) + lib /nologo /out:xchatcommon.lib $(COMMON_OBJECTS) + +dirent-win32.lib: dirent-win32.obj + lib /nologo /out:dirent-win32.lib dirent-win32.obj + +.c.obj:: + $(CC) $(CFLAGS) $(GLIB) $< + +clean: + @del *.obj + @del xchatcommon.lib + @del dirent-win32.lib diff --git a/src/common/modes.c b/src/common/modes.c index 1acf7f54..6eb63f3b 100644 --- a/src/common/modes.c +++ b/src/common/modes.c @@ -789,20 +789,20 @@ inbound_005 (server * serv, char *word[]) } /* use /NICKSERV */ - if (strcasecmp (word[w] + 8, "RusNet") == 0) + if (g_ascii_strcasecmp (word[w] + 8, "RusNet") == 0) serv->nickservtype = 1; - else if (strcasecmp (word[w] + 8, "UniBG") == 0) + else if (g_ascii_strcasecmp (word[w] + 8, "UniBG") == 0) serv->nickservtype = 3; - else if (strcasecmp (word[w] + 8, "QuakeNet") == 0) + else if (g_ascii_strcasecmp (word[w] + 8, "QuakeNet") == 0) serv->nickservtype = 4; } else if (strncmp (word[w], "CASEMAPPING=", 12) == 0) { if (strcmp (word[w] + 12, "ascii") == 0) /* bahamut */ - serv->p_cmp = (void *)strcasecmp; + serv->p_cmp = (void *)g_ascii_strcasecmp; } else if (strncmp (word[w], "CHARSET=", 8) == 0) { - if (strcasecmp (word[w] + 8, "UTF-8") == 0) + if (g_ascii_strcasecmp (word[w] + 8, "UTF-8") == 0) { server_set_encoding (serv, "UTF-8"); } diff --git a/src/common/msproxy.c b/src/common/msproxy.c index 9c85394d..5103233a 100644 --- a/src/common/msproxy.c +++ b/src/common/msproxy.c @@ -26,9 +26,12 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <unistd.h> #include <fcntl.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #define WANTSOCKET #define WANTARPA #include "inet.h" diff --git a/src/common/network.c b/src/common/network.c index 0c409506..eba24b05 100644 --- a/src/common/network.c +++ b/src/common/network.c @@ -21,9 +21,12 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> -#include <unistd.h> #include <glib.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #include "../../config.h" /* grab USE_IPV6 and LOOKUPD defines */ #define WANTSOCKET diff --git a/src/common/notify.c b/src/common/notify.c index 04795849..9c6e54de 100644 --- a/src/common/notify.c +++ b/src/common/notify.c @@ -22,9 +22,12 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include <unistd.h> #include <time.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #include "xchat.h" #include "notify.h" #include "cfgfiles.h" diff --git a/src/common/outbound.c b/src/common/outbound.c index 2add05fd..872ef50b 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -30,9 +30,9 @@ #ifndef WIN32 #include <sys/wait.h> +#include <unistd.h> #endif -#include <unistd.h> #include <time.h> #include <signal.h> #include <sys/stat.h> @@ -617,13 +617,13 @@ cmd_clear (struct session *sess, char *tbuf, char *word[], char *word_eol[]) GSList *list = sess_list; char *reason = word_eol[2]; - if (strcasecmp (reason, "HISTORY") == 0) + if (g_ascii_strcasecmp (reason, "HISTORY") == 0) { history_free (&sess->history); return TRUE; } - if (strncasecmp (reason, "all", 3) == 0) + if (g_ascii_strncasecmp (reason, "all", 3) == 0) { while (list) { @@ -750,26 +750,26 @@ cmd_dcc (struct session *sess, char *tbuf, char *word[], char *word_eol[]) char *type = word[2]; if (*type) { - if (!strcasecmp (type, "HELP")) + if (!g_ascii_strcasecmp (type, "HELP")) return FALSE; - if (!strcasecmp (type, "CLOSE")) + if (!g_ascii_strcasecmp (type, "CLOSE")) { if (*word[3] && *word[4]) { goodtype = 0; - if (!strcasecmp (word[3], "SEND")) + if (!g_ascii_strcasecmp (word[3], "SEND")) { dcc = find_dcc (word[4], word[5], TYPE_SEND); dcc_abort (sess, dcc); goodtype = TRUE; } - if (!strcasecmp (word[3], "GET")) + if (!g_ascii_strcasecmp (word[3], "GET")) { dcc = find_dcc (word[4], word[5], TYPE_RECV); dcc_abort (sess, dcc); goodtype = TRUE; } - if (!strcasecmp (word[3], "CHAT")) + if (!g_ascii_strcasecmp (word[3], "CHAT")) { dcc = find_dcc (word[4], "", TYPE_CHATRECV); if (!dcc) @@ -789,20 +789,20 @@ cmd_dcc (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } return FALSE; } - if ((!strcasecmp (type, "CHAT")) || (!strcasecmp (type, "PCHAT"))) + if ((!g_ascii_strcasecmp (type, "CHAT")) || (!g_ascii_strcasecmp (type, "PCHAT"))) { char *nick = word[3]; - int passive = (!strcasecmp(type, "PCHAT")) ? 1 : 0; + int passive = (!g_ascii_strcasecmp(type, "PCHAT")) ? 1 : 0; if (*nick) dcc_chat (sess, nick, passive); return TRUE; } - if (!strcasecmp (type, "LIST")) + if (!g_ascii_strcasecmp (type, "LIST")) { dcc_show_list (sess); return TRUE; } - if (!strcasecmp (type, "GET")) + if (!g_ascii_strcasecmp (type, "GET")) { char *nick = word[3]; char *file = word[4]; @@ -820,18 +820,18 @@ cmd_dcc (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } return TRUE; } - if ((!strcasecmp (type, "SEND")) || (!strcasecmp (type, "PSEND"))) + if ((!g_ascii_strcasecmp (type, "SEND")) || (!g_ascii_strcasecmp (type, "PSEND"))) { int i = 3, maxcps; char *nick, *file; - int passive = (!strcasecmp(type, "PSEND")) ? 1 : 0; + int passive = (!g_ascii_strcasecmp(type, "PSEND")) ? 1 : 0; nick = word[i]; if (!*nick) return FALSE; maxcps = prefs.dcc_max_send_cps; - if (!strncasecmp(nick, "-maxcps=", 8)) + if (!g_ascii_strncasecmp(nick, "-maxcps=", 8)) { maxcps = atoi(nick + 8); i++; @@ -1312,7 +1312,7 @@ cmd_menu (struct session *sess, char *tbuf, char *word[], char *word_eol[]) *p = '/'; } - if (!strcasecmp (word[idx], "ADD")) + if (!g_ascii_strcasecmp (word[idx], "ADD")) { if (toggle) { @@ -1327,7 +1327,7 @@ cmd_menu (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return TRUE; } - if (!strcasecmp (word[idx], "DEL")) + if (!g_ascii_strcasecmp (word[idx], "DEL")) { menu_del (tbuf, label); return TRUE; @@ -2045,7 +2045,7 @@ cmd_gui (struct session *sess, char *tbuf, char *word[], char *word_eol[]) case 0xc0851aaa: fe_message (word[3], FE_MSG_INFO|FE_MSG_MARKUP); break; /* MSGBOX */ case 0x0035dafd: fe_ctrl_gui (sess, 1, 0); break; /* SHOW */ case 0x0033155f: /* MENU */ - if (!strcasecmp (word[3], "TOGGLE")) + if (!g_ascii_strcasecmp (word[3], "TOGGLE")) fe_ctrl_gui (sess, 6, 0); else return FALSE; @@ -2247,25 +2247,25 @@ cmd_ignore (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } return TRUE; } - if (!strcasecmp (word[i], "UNIGNORE")) + if (!g_ascii_strcasecmp (word[i], "UNIGNORE")) type |= IG_UNIG; - else if (!strcasecmp (word[i], "ALL")) + else if (!g_ascii_strcasecmp (word[i], "ALL")) type |= IG_PRIV | IG_NOTI | IG_CHAN | IG_CTCP | IG_INVI | IG_DCC; - else if (!strcasecmp (word[i], "PRIV")) + else if (!g_ascii_strcasecmp (word[i], "PRIV")) type |= IG_PRIV; - else if (!strcasecmp (word[i], "NOTI")) + else if (!g_ascii_strcasecmp (word[i], "NOTI")) type |= IG_NOTI; - else if (!strcasecmp (word[i], "CHAN")) + else if (!g_ascii_strcasecmp (word[i], "CHAN")) type |= IG_CHAN; - else if (!strcasecmp (word[i], "CTCP")) + else if (!g_ascii_strcasecmp (word[i], "CTCP")) type |= IG_CTCP; - else if (!strcasecmp (word[i], "INVI")) + else if (!g_ascii_strcasecmp (word[i], "INVI")) type |= IG_INVI; - else if (!strcasecmp (word[i], "QUIET")) + else if (!g_ascii_strcasecmp (word[i], "QUIET")) quiet = 1; - else if (!strcasecmp (word[i], "NOSAVE")) + else if (!g_ascii_strcasecmp (word[i], "NOSAVE")) type |= IG_NOSAVE; - else if (!strcasecmp (word[i], "DCC")) + else if (!g_ascii_strcasecmp (word[i], "DCC")) type |= IG_DCC; else { @@ -2456,12 +2456,12 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[]) #ifdef USE_PLUGIN len = strlen (word[2]); #ifdef WIN32 - if (len > 4 && strcasecmp (".dll", word[2] + len - 4) == 0) + if (len > 4 && g_ascii_strcasecmp (".dll", word[2] + len - 4) == 0) #else #if defined(__hpux) - if (len > 3 && strcasecmp (".sl", word[2] + len - 3) == 0) + if (len > 3 && g_ascii_strcasecmp (".sl", word[2] + len - 3) == 0) #else - if (len > 3 && strcasecmp (".so", word[2] + len - 3) == 0) + if (len > 3 && g_ascii_strcasecmp (".so", word[2] + len - 3) == 0) #endif #endif { @@ -2613,8 +2613,8 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) else { /* mask out passwords */ - if (strcasecmp (nick, "nickserv") == 0 && - strncasecmp (msg, "identify ", 9) == 0) + if (g_ascii_strcasecmp (nick, "nickserv") == 0 && + g_ascii_strncasecmp (msg, "identify ", 9) == 0) msg = "identify ****"; EMIT_SIGNAL (XP_TE_MSGSEND, sess, nick, msg, NULL, NULL, 0); } @@ -2825,7 +2825,7 @@ cmd_reconnect (struct session *sess, char *tbuf, char *word[], char *word_eol[]) prefs.recon_delay = 0; - if (!strcasecmp (word[2], "ALL")) + if (!g_ascii_strcasecmp (word[2], "ALL")) { list = serv_list; while (list) @@ -2881,6 +2881,23 @@ cmd_recv (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return FALSE; } +#if 0 /* manual command for flushing prefs to disk, but we use an autosave-upon-set approach instead */ +static int +cmd_saveconf (struct session *sess, char *tbuf, char *word[], char *word_eol[]) +{ + if (save_config ()) + { + PrintText (sess, "Settings have been saved successfully.\n"); + } + else + { + PrintText (sess, "Error saving settings.\n"); + } + + return TRUE; +} +#endif + static int cmd_say (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { @@ -2980,7 +2997,7 @@ parse_irc_url (char *url, char *server_name[], char *port[], char *channel[], in { char *co; #ifdef USE_OPENSSL - if (strncasecmp ("ircs://", url, 7) == 0) + if (g_ascii_strncasecmp ("ircs://", url, 7) == 0) { *use_ssl = TRUE; *server_name = url + 7; @@ -2988,7 +3005,7 @@ parse_irc_url (char *url, char *server_name[], char *port[], char *channel[], in } #endif - if (strncasecmp ("irc://", url, 6) == 0) + if (g_ascii_strncasecmp ("irc://", url, 6) == 0) { *server_name = url + 6; #ifdef USE_OPENSSL @@ -3059,7 +3076,7 @@ cmd_server (struct session *sess, char *tbuf, char *word[], char *word_eol[]) sess->server->network = NULL; /* dont clear it for /servchan */ - if (strncasecmp (word_eol[1], "SERVCHAN ", 9)) + if (g_ascii_strncasecmp (word_eol[1], "SERVCHAN ", 9)) sess->willjoinchannel[0] = 0; if (channel) @@ -3189,7 +3206,7 @@ cmd_unignore (struct session *sess, char *tbuf, char *word[], { if (ignore_del (mask, NULL)) { - if (strcasecmp (arg, "QUIET")) + if (g_ascii_strcasecmp (arg, "QUIET")) EMIT_SIGNAL (XP_TE_IGNOREREMOVE, sess, mask, NULL, NULL, NULL, 0); } return TRUE; @@ -3205,12 +3222,12 @@ cmd_unload (struct session *sess, char *tbuf, char *word[], char *word_eol[]) len = strlen (word[2]); #ifdef WIN32 - if (len > 4 && strcasecmp (word[2] + len - 4, ".dll") == 0) + if (len > 4 && g_ascii_strcasecmp (word[2] + len - 4, ".dll") == 0) #else #if defined(__hpux) - if (len > 3 && strcasecmp (word[2] + len - 3, ".sl") == 0) + if (len > 3 && g_ascii_strcasecmp (word[2] + len - 3, ".sl") == 0) #else - if (len > 3 && strcasecmp (word[2] + len - 3, ".so") == 0) + if (len > 3 && g_ascii_strcasecmp (word[2] + len - 3, ".so") == 0) #endif #endif by_file = TRUE; @@ -3240,7 +3257,7 @@ find_server_from_hostname (char *hostname) while (list) { serv = list->data; - if (!strcasecmp (hostname, serv->hostname) && serv->connected) + if (!g_ascii_strcasecmp (hostname, serv->hostname) && serv->connected) return serv; list = list->next; } @@ -3293,7 +3310,7 @@ cmd_url (struct session *sess, char *tbuf, char *word[], char *word_eol[]) /* maybe we're already connected to this net */ /* check for "FreeNode" */ - net = servlist_net_find (server_name, NULL, strcasecmp); + net = servlist_net_find (server_name, NULL, g_ascii_strcasecmp); /* check for "irc.eu.freenode.net" */ if (!net) net = servlist_net_find_from_server (server_name); @@ -3633,6 +3650,9 @@ const struct commands xc_cmds[] = { #endif {"RECV", cmd_recv, 1, 0, 1, N_("RECV <text>, send raw data to xchat, as if it was received from the irc server")}, +#if 0 + {"SAVECONF", cmd_saveconf, 0, 0, 1, N_("SAVECONF, saves the current settings to disk")}, +#endif {"SAY", cmd_say, 0, 0, 1, N_("SAY <text>, sends the text to the object in the current window")}, {"SEND", cmd_send, 0, 0, 1, N_("SEND <nick> [<file>]")}, @@ -3685,7 +3705,7 @@ const struct commands xc_cmds[] = { static int command_compare (const void *a, const void *b) { - return strcasecmp (a, ((struct commands *)b)->name); + return g_ascii_strcasecmp (a, ((struct commands *)b)->name); } static struct commands * @@ -4257,7 +4277,7 @@ handle_command (session *sess, char *cmd, int check_spch) while (list) { pop = (struct popup *) list->data; - if (!strcasecmp (pop->name, word[1])) + if (!g_ascii_strcasecmp (pop->name, word[1])) { user_command (sess, tbuf, pop->cmd, word, word_eol); user_cmd = TRUE; diff --git a/src/common/plugin-timer.c b/src/common/plugin-timer.c index f09074a8..431ce8ab 100644 --- a/src/common/plugin-timer.c +++ b/src/common/plugin-timer.c @@ -4,7 +4,7 @@ #include "xchat-plugin.h" #ifdef WIN32 -#define strcasecmp stricmp +#define g_ascii_strcasecmp stricmp #endif static xchat_plugin *ph; /* plugin handle */ @@ -151,25 +151,25 @@ timer_cb (char *word[], char *word_eol[], void *userdata) return XCHAT_EAT_XCHAT; } - if (strcasecmp (word[2], "-quiet") == 0) + if (g_ascii_strcasecmp (word[2], "-quiet") == 0) { quiet = TRUE; offset++; } - if (strcasecmp (word[2 + offset], "-delete") == 0) + if (g_ascii_strcasecmp (word[2 + offset], "-delete") == 0) { timer_del_ref (atoi (word[3 + offset]), quiet); return XCHAT_EAT_XCHAT; } - if (strcasecmp (word[2 + offset], "-refnum") == 0) + if (g_ascii_strcasecmp (word[2 + offset], "-refnum") == 0) { ref = atoi (word[3 + offset]); offset += 2; } - if (strcasecmp (word[2 + offset], "-repeat") == 0) + if (g_ascii_strcasecmp (word[2 + offset], "-repeat") == 0) { repeat = atoi (word[3 + offset]); offset += 2; diff --git a/src/common/plugin.c b/src/common/plugin.c index ada4d3be..0a265d16 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -20,6 +20,14 @@ #include <string.h> #include <stdarg.h> #include <stdio.h> +#include <fcntl.h> +#include <sys/stat.h> + +#ifdef WIN32 +#include <io.h> +#else +#include <unistd.h> +#endif #include "xchat.h" #include "fe.h" @@ -262,6 +270,12 @@ plugin_add (session *sess, char *filename, void *handle, void *init_func, pl->xchat_send_modes = xchat_send_modes; pl->xchat_strip = xchat_strip; pl->xchat_free = xchat_free; + pl->xchat_pluginpref_set_str = xchat_pluginpref_set_str; + pl->xchat_pluginpref_get_str = xchat_pluginpref_get_str; + pl->xchat_pluginpref_set_int = xchat_pluginpref_set_int; + pl->xchat_pluginpref_get_int = xchat_pluginpref_get_int; + pl->xchat_pluginpref_delete = xchat_pluginpref_delete; + pl->xchat_pluginpref_list = xchat_pluginpref_list; /* incase new plugins are loaded on older xchat */ pl->xchat_dummy4 = xchat_dummy; @@ -295,9 +309,9 @@ plugin_kill (char *name, int by_filename) { pl = list->data; /* static-plugins (plugin-timer.c) have a NULL filename */ - if ((by_filename && pl->filename && strcasecmp (name, pl->filename) == 0) || - (by_filename && pl->filename && strcasecmp (name, file_part (pl->filename)) == 0) || - (!by_filename && strcasecmp (name, pl->name) == 0)) + if ((by_filename && pl->filename && g_ascii_strcasecmp (name, pl->filename) == 0) || + (by_filename && pl->filename && g_ascii_strcasecmp (name, file_part (pl->filename)) == 0) || + (!by_filename && g_ascii_strcasecmp (name, pl->name) == 0)) { /* statically linked plugins have a NULL filename */ if (pl->filename != NULL && !pl->fake) @@ -458,12 +472,12 @@ plugin_hook_find (GSList *list, int type, char *name) hook = list->data; if (hook->type == type) { - if (strcasecmp (hook->name, name) == 0) + if (g_ascii_strcasecmp (hook->name, name) == 0) return list; if (type == HOOK_SERVER) { - if (strcasecmp (hook->name, "RAW LINE") == 0) + if (g_ascii_strcasecmp (hook->name, "RAW LINE") == 0) return list; } } @@ -933,8 +947,8 @@ xchat_find_context (xchat_plugin *ph, const char *servname, const char *channel) if (servname == NULL || rfc_casecmp (servname, serv->servername) == 0 || - strcasecmp (servname, serv->hostname) == 0 || - strcasecmp (servname, netname) == 0) + g_ascii_strcasecmp (servname, serv->hostname) == 0 || + g_ascii_strcasecmp (servname, netname) == 0) { if (channel == NULL) return serv->front_session; @@ -996,13 +1010,20 @@ xchat_get_info (xchat_plugin *ph, const char *id) return XCHATLIBDIR; case 0x14f51cd8: /* version */ +#ifdef WIN32 + return XCHAT_RELEASE; +#else return PACKAGE_VERSION; +#endif case 0xdd9b1abd: /* xchatdir */ return get_xdir_utf8 (); case 0xe33f6c4a: /* xchatdirfs */ return get_xdir_fs (); + + case 0x3d1e70d7: /* wdk_version */ + return PACKAGE_VERSION; } sess = ph->context; @@ -1100,7 +1121,7 @@ xchat_get_prefs (xchat_plugin *ph, const char *name, const char **string, int *i do { - if (!strcasecmp (name, vars[i].name)) + if (!g_ascii_strcasecmp (name, vars[i].name)) { switch (vars[i].type) { @@ -1567,3 +1588,239 @@ xchat_free (xchat_plugin *ph, void *ptr) { g_free (ptr); } + +static int +xchat_pluginpref_set_str_real (xchat_plugin *pl, const char *var, const char *value, int mode) /* mode: 0 = delete, 1 = save */ +{ + FILE *fpIn; + int fhOut; + int prevSetting; + char confname[64]; + char confname_tmp[69]; + char buffer[512]; /* the same as in cfg_put_str */ + char buffer_tmp[512]; + char *canon; + + canon = g_strdup (pl->name); + canonalize_key (canon); + sprintf (confname, "plugin_%s.conf", canon); + g_free (canon); + sprintf (confname_tmp, "%s.new", confname); + + fhOut = xchat_open_file (confname_tmp, O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE); + fpIn = xchat_fopen_file (confname, "r", 0); + + if (fhOut == -1) /* unable to save, abort */ + { + return 0; + } + else if (fpIn == NULL) /* no previous config file, no parsing */ + { + if (mode) + { + sprintf (buffer, "%s = %s\n", var, value); + write (fhOut, buffer, strlen (buffer)); + close (fhOut); + + sprintf (buffer, "%s/%s", get_xdir_fs (), confname); + sprintf (buffer_tmp, "%s/%s", get_xdir_fs (), confname_tmp); + +#ifdef WIN32 + unlink (buffer); +#endif + + if (rename (buffer_tmp, buffer) == 0) + { + return 1; + } + else + { + return 0; + } + } + else + { + /* mode = 0, we want to delete but the config file and thus the given setting does not exist, we're ready */ + close (fhOut); + return 1; + } + } + else /* existing config file, preserve settings and find & replace current var value if any */ + { + prevSetting = 0; + + while (fscanf (fpIn, " %[^\n]", &buffer) != EOF) /* read whole lines including whitespaces */ + { + sprintf (buffer_tmp, "%s ", var); /* add one space, this way it works against var - var2 checks too */ + + if (strncmp (buffer_tmp, buffer, strlen (var) + 1) == 0) /* given setting already exists */ + { + if (mode) /* overwrite the existing matching setting if we are in save mode */ + { + sprintf (buffer, "%s = %s\n", var, value); + } + else /* erase the setting in delete mode */ + { + strcpy (buffer, ""); + } + + prevSetting = 1; + } + else + { + strcat (buffer, "\n"); /* preserve the existing different settings */ + } + + write (fhOut, buffer, strlen (buffer)); + } + + fclose (fpIn); + + if (!prevSetting && mode) /* var doesn't exist currently, append if we're in save mode */ + { + sprintf (buffer, "%s = %s\n", var, value); + write (fhOut, buffer, strlen (buffer)); + } + + close (fhOut); + + sprintf (buffer, "%s/%s", get_xdir_fs (), confname); + sprintf (buffer_tmp, "%s/%s", get_xdir_fs (), confname_tmp); + +#ifdef WIN32 + unlink (buffer); +#endif + + if (rename (buffer_tmp, buffer) == 0) + { + return 1; + } + else + { + return 0; + } + } +} + +int +xchat_pluginpref_set_str (xchat_plugin *pl, const char *var, const char *value) +{ + return xchat_pluginpref_set_str_real (pl, var, value, 1); +} + +int +xchat_pluginpref_get_str (xchat_plugin *pl, const char *var, char *dest) +{ + int fh; + int l; + char confname[64]; + char *canon; + char *cfg; + struct stat st; + + canon = g_strdup (pl->name); + canonalize_key (canon); + sprintf (confname, "plugin_%s.conf", canon); + g_free (canon); + + /* partly borrowed from palette.c */ + fh = xchat_open_file (confname, O_RDONLY, 0, 0); + + if (fh == -1) + { + return 0; + } + + fstat (fh, &st); + cfg = malloc (st.st_size + 1); + + if (!cfg) + { + close (fh); + return 0; + } + + cfg[0] = '\0'; + l = read (fh, cfg, st.st_size); + + if (l >= 0) + { + cfg[l] = '\0'; + } + + if (!cfg_get_str (cfg, var, dest, 512)) /* dest_len is the same as buffer size in set */ + { + free (cfg); + close (fh); + return 0; + } + + free (cfg); + close (fh); + return 1; +} + +int +xchat_pluginpref_set_int (xchat_plugin *pl, const char *var, int value) +{ + char buffer[12]; + + sprintf (buffer, "%d", value); + return xchat_pluginpref_set_str_real (pl, var, buffer, 1); +} + +int +xchat_pluginpref_get_int (xchat_plugin *pl, const char *var) +{ + char buffer[12]; + + if (xchat_pluginpref_get_str (pl, var, buffer)) + { + return atoi (buffer); + } + else + { + return -1; + } +} + +int +xchat_pluginpref_delete (xchat_plugin *pl, const char *var) +{ + return xchat_pluginpref_set_str_real (pl, var, 0, 0); +} + +int +xchat_pluginpref_list (xchat_plugin *pl, char* dest) +{ + FILE *fpIn; + char confname[64]; + char buffer[512]; /* the same as in cfg_put_str */ + char *token; + + token = g_strdup (pl->name); + canonalize_key (token); + sprintf (confname, "plugin_%s.conf", token); + g_free (token); + + fpIn = xchat_fopen_file (confname, "r", 0); + + if (fpIn == NULL) /* no existing config file, no parsing */ + { + return 0; + } + else /* existing config file, get list of settings */ + { + strcpy (dest, ""); /* clean up garbage */ + while (fscanf (fpIn, " %[^\n]", &buffer) != EOF) /* read whole lines including whitespaces */ + { + token = strtok (buffer, "="); + strncat (dest, token, strlen (token) - 1); + strcat (dest, ","); + } + + fclose (fpIn); + } + + return 1; +} diff --git a/src/common/plugin.h b/src/common/plugin.h index b0c89d1b..8c347d51 100644 --- a/src/common/plugin.h +++ b/src/common/plugin.h @@ -98,6 +98,21 @@ struct _xchat_plugin int flags); void (*xchat_free) (xchat_plugin *ph, void *ptr); + int (*xchat_pluginpref_set_str) (xchat_plugin *ph, + const char *var, + const char *value); + int (*xchat_pluginpref_get_str) (xchat_plugin *ph, + const char *var, + char *dest); + int (*xchat_pluginpref_set_int) (xchat_plugin *ph, + const char *var, + int value); + int (*xchat_pluginpref_get_int) (xchat_plugin *ph, + const char *var); + int (*xchat_pluginpref_delete) (xchat_plugin *ph, + const char *var); + int (*xchat_pluginpref_list) (xchat_plugin *ph, + char *dest); void *(*xchat_dummy4) (xchat_plugin *ph); void *(*xchat_dummy3) (xchat_plugin *ph); void *(*xchat_dummy2) (xchat_plugin *ph); diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 338a3b18..d8a6be7c 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -18,13 +18,16 @@ /* IRC RFC1459(+commonly used extensions) protocol implementation */ -#include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <stdarg.h> +#ifndef WIN32 +#include <unistd.h> +#endif + #include "xchat.h" #include "ctcp.h" #include "fe.h" @@ -472,12 +475,12 @@ process_numeric (session * sess, int n, } /* use /NICKSERV */ - if (strcasecmp (word[7], "DALnet") == 0 || - strcasecmp (word[7], "BRASnet") == 0) + if (g_ascii_strcasecmp (word[7], "DALnet") == 0 || + g_ascii_strcasecmp (word[7], "BRASnet") == 0) serv->nickservtype = 1; /* use /NS */ - else if (strcasecmp (word[7], "FreeNode") == 0) + else if (g_ascii_strcasecmp (word[7], "FreeNode") == 0) serv->nickservtype = 2; goto def; @@ -1072,9 +1075,9 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) { text[len - 1] = 0; text++; - if (strncasecmp (text, "ACTION", 6) != 0) + if (g_ascii_strncasecmp (text, "ACTION", 6) != 0) flood_check (nick, ip, serv, sess, 0); - if (strncasecmp (text, "DCC ", 4) == 0) + if (g_ascii_strncasecmp (text, "DCC ", 4) == 0) /* redo this with handle_quotes TRUE */ process_data_init (word[1], word_eol[1], word, word_eol, TRUE, FALSE); ctcp_handle (sess, to, nick, ip, text, word, word_eol, id); diff --git a/src/common/server.c b/src/common/server.c index db0af9ca..c8cc59e0 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -26,7 +26,6 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <unistd.h> #include <errno.h> #include <fcntl.h> @@ -37,6 +36,7 @@ #ifndef WIN32 #include <signal.h> #include <sys/wait.h> +#include <unistd.h> #else #include <winbase.h> #endif @@ -67,7 +67,7 @@ #endif #ifdef WIN32 -#include "identd.c" +#include "identd.h" #endif #ifdef USE_LIBPROXY @@ -238,17 +238,17 @@ tcp_send_len (server *serv, char *buf, int len) dbuf[len + 1] = 0; /* privmsg and notice get a lower priority */ - if (strncasecmp (dbuf + 1, "PRIVMSG", 7) == 0 || - strncasecmp (dbuf + 1, "NOTICE", 6) == 0) + if (g_ascii_strncasecmp (dbuf + 1, "PRIVMSG", 7) == 0 || + g_ascii_strncasecmp (dbuf + 1, "NOTICE", 6) == 0) { dbuf[0] = 1; } else { /* WHO/MODE get the lowest priority */ - if (strncasecmp (dbuf + 1, "WHO ", 4) == 0 || + if (g_ascii_strncasecmp (dbuf + 1, "WHO ", 4) == 0 || /* but only MODE queries, not changes */ - (strncasecmp (dbuf + 1, "MODE", 4) == 0 && + (g_ascii_strncasecmp (dbuf + 1, "MODE", 4) == 0 && strchr (dbuf, '-') == NULL && strchr (dbuf, '+') == NULL)) dbuf[0] = 0; @@ -310,12 +310,17 @@ server_inline (server *serv, char *line, int len) { char *utf_line_allocated = NULL; +#ifdef WIN32 + char *cleaned_line; + int cleaned_len; +#endif + /* Checks whether we're set to use UTF-8 charset */ if (serv->using_irc || /* 1. using CP1252/UTF-8 Hybrid */ (serv->encoding == NULL && prefs.utf8_locale) || /* OR 2. using system default->UTF-8 */ (serv->encoding != NULL && /* OR 3. explicitly set to UTF-8 */ - (strcasecmp (serv->encoding, "UTF8") == 0 || - strcasecmp (serv->encoding, "UTF-8") == 0))) + (g_ascii_strcasecmp (serv->encoding, "UTF8") == 0 || + g_ascii_strcasecmp (serv->encoding, "UTF-8") == 0))) { /* The user has the UTF-8 charset set, either via /charset command or from his UTF-8 locale. Thus, we first try the @@ -396,11 +401,23 @@ server_inline (server *serv, char *line, int len) } } +#ifdef WIN32 + cleaned_line = text_replace_non_bmp (line, len, &cleaned_len); + if (cleaned_line != NULL ) { + line = cleaned_line; + len = cleaned_len; + } +#endif + fe_add_rawlog (serv, line, len, FALSE); /* let proto-irc.c handle it */ serv->p_inline (serv, line, len); +#ifdef WIN32 + g_free (cleaned_line); +#endif + if (utf_line_allocated != NULL) /* only if a special copy was allocated */ g_free (utf_line_allocated); } @@ -844,33 +861,6 @@ server_flush_queue (server *serv) fe_set_throttle (serv); } -#ifdef WIN32 - -static int -waitline2 (GIOChannel *source, char *buf, int bufsize) -{ - int i = 0; - int len; - - while (1) - { - if (g_io_channel_read (source, &buf[i], 1, &len) != G_IO_ERROR_NONE) - return -1; - if (buf[i] == '\n' || bufsize == i + 1) - { - buf[i] = 0; - return i; - } - i++; - } -} - -#else - -#define waitline2(source,buf,size) waitline(serv->childread,buf,size,0) - -#endif - /* connect() successed */ static void @@ -1394,12 +1384,7 @@ base64_encode (char *to, char *from, unsigned int len) static int http_read_line (int print_fd, int sok, char *buf, int len) { -#ifdef WIN32 - /* make sure waitline() uses recv() or it'll fail on win32 */ - len = waitline (sok, buf, len, FALSE); -#else len = waitline (sok, buf, len, TRUE); -#endif if (len >= 1) { /* print the message out (send it to the parent process) */ @@ -1795,7 +1780,11 @@ server_connect (server *serv, char *hostname, int port, int no_login) } #endif serv->childpid = pid; +#ifdef WIN32 + serv->iotag = fe_input_add (serv->childread, FIA_READ|FIA_FD, server_read_child, +#else serv->iotag = fe_input_add (serv->childread, FIA_READ, server_read_child, +#endif serv); } @@ -1835,10 +1824,10 @@ server_set_encoding (server *serv, char *new_encoding) space[0] = 0; /* server_inline() uses these flags */ - if (!strcasecmp (serv->encoding, "CP1255") || - !strcasecmp (serv->encoding, "WINDOWS-1255")) + if (!g_ascii_strcasecmp (serv->encoding, "CP1255") || + !g_ascii_strcasecmp (serv->encoding, "WINDOWS-1255")) serv->using_cp1255 = TRUE; - else if (!strcasecmp (serv->encoding, "IRC")) + else if (!g_ascii_strcasecmp (serv->encoding, "IRC")) serv->using_irc = TRUE; } } diff --git a/src/common/servlist.c b/src/common/servlist.c index 66bc8115..aa32aa4d 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -21,7 +21,10 @@ #include <string.h> #include <sys/types.h> #include <sys/stat.h> + +#ifndef WIN32 #include <unistd.h> +#endif #include "xchat.h" #include <glib.h> @@ -585,7 +588,7 @@ servlist_connect_by_netname (session *sess, char *network, gboolean join) { net = list->data; - if (strcasecmp (net->name, network) == 0) + if (g_ascii_strcasecmp (net->name, network) == 0) { servlist_connect (sess, net, join); return 1; @@ -730,7 +733,7 @@ servlist_net_find_from_server (char *server_name) while (slist) { serv = slist->data; - if (strcasecmp (serv->hostname, server_name) == 0) + if (g_ascii_strcasecmp (serv->hostname, server_name) == 0) return net; slist = slist->next; } @@ -1015,7 +1018,7 @@ servlist_check_encoding (char *charset) if (c) c[0] = 0; - if (!strcasecmp (charset, "IRC")) /* special case */ + if (!g_ascii_strcasecmp (charset, "IRC")) /* special case */ { if (c) c[0] = ' '; @@ -1090,8 +1093,8 @@ servlist_save (void) fprintf (fp, "J=%s\n", net->autojoin); if (net->nickserv) fprintf (fp, "B=%s\n", net->nickserv); - if (net->encoding && strcasecmp (net->encoding, "System") && - strcasecmp (net->encoding, "System default")) + 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)) diff --git a/src/common/ssl.c b/src/common/ssl.c index a18ad47c..daa7416b 100644 --- a/src/common/ssl.c +++ b/src/common/ssl.c @@ -17,12 +17,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#include "inet.h" /* make it first to avoid macro redefinitions */ #include <openssl/ssl.h> /* SSL_() */ #include <openssl/err.h> /* ERR_() */ #include <time.h> /* asctime() */ #include <string.h> /* strncpy() */ #include "ssl.h" /* struct cert_info */ -#include "inet.h" #include "../../config.h" /* HAVE_SNPRINTF */ #ifndef HAVE_SNPRINTF diff --git a/src/common/text.c b/src/common/text.c index 6b111742..f8afc4b3 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -19,13 +19,16 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <unistd.h> #include <ctype.h> #include <time.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> + +#ifndef WIN32 +#include <unistd.h> #include <sys/mman.h> +#endif #include "xchat.h" #include <glib.h> @@ -271,9 +274,15 @@ scrollback_load (session *sess) char *text; time_t stamp; int lines; + +#ifdef WIN32 + char *cleaned_text; + int cleaned_len; +#else char *map, *end_map; struct stat statbuf; const char *begin, *eol; +#endif if (sess->text_scrollback == SET_DEFAULT) { @@ -293,6 +302,7 @@ scrollback_load (session *sess) if (fh == -1) return; +#ifndef WIN32 if (fstat (fh, &statbuf) < 0) return; @@ -301,7 +311,7 @@ scrollback_load (session *sess) return; end_map = map + statbuf.st_size; - + lines = 0; begin = map; while (begin < end_map) @@ -314,11 +324,11 @@ scrollback_load (session *sess) eol = end_map; n_bytes = MIN (eol - begin, sizeof (buf) - 1); - + strncpy (buf, begin, n_bytes); buf[n_bytes] = 0; - + if (buf[0] == 'T') { if (sizeof (time_t) == 4) @@ -350,6 +360,45 @@ scrollback_load (session *sess) } munmap (map, statbuf.st_size); +#else + lines = 0; + while (waitline (fh, buf, sizeof buf, FALSE) != -1) + { + if (buf[0] == 'T') + { + if (sizeof (time_t) == 4) + stamp = strtoul (buf + 2, NULL, 10); + else + stamp = strtoull (buf + 2, NULL, 10); /* just incase time_t is 64 bits */ + text = strchr (buf + 3, ' '); + if (text) + { + text = strip_color (text + 1, -1, STRIP_COLOR); + cleaned_text = text_replace_non_bmp (text, -1, &cleaned_len); + if (cleaned_text != NULL) + { + g_free (text); + text = cleaned_text; + } + fe_print_text (sess, text, stamp); + g_free (text); + } + lines++; + } + } + + sess->scrollwritten = lines; + + if (lines) + { + text = ctime (&stamp); + text[24] = 0; /* get rid of the \n */ + snprintf (buf, sizeof (buf), "\n*\t%s %s\n\n", _("Loaded log from"), text); + fe_print_text (sess, buf, 0); + /*EMIT_SIGNAL (XP_TE_GENMSG, sess, "*", buf, NULL, NULL, NULL, 0);*/ + } +#endif + close (fh); } @@ -637,6 +686,13 @@ get_stamp_str (char *fmt, time_t tim, char **ret) } len = strftime (dest, sizeof (dest), fmt, localtime (&tim)); +#ifdef WIN32 + if (!len) + { + /* use failsafe format until a correct one is specified */ + len = strftime (dest, sizeof (dest), "[%H:%M]", localtime (&tim)); + } +#endif if (len) { if (prefs.utf8_locale) @@ -812,6 +868,46 @@ iso_8859_1_to_utf8 (unsigned char *text, int len, gsize *bytes_written) return res; } +#ifdef WIN32 +/* replace characters outside of the Basic Multilingual Plane with + * replacement characters (0xFFFD) */ +char * +text_replace_non_bmp (char *utf8_input, int input_length, glong *output_length) +{ + gunichar *ucs4_text; + gunichar suspect; + gchar *utf8_text; + glong ucs4_length; + glong index; + + ucs4_text = g_utf8_to_ucs4_fast (utf8_input, input_length, &ucs4_length); + + /* replace anything not in the Basic Multilingual Plane + * (code points above 0xFFFF) with the replacement + * character */ + for (index = 0; index < ucs4_length; index++) + { + suspect = ucs4_text[index]; + if ((suspect >= 0x1D173 && suspect <= 0x1D17A) + || (suspect >= 0xE0001 && suspect <= 0xE007F)) + { + ucs4_text[index] = 0xFFFD; /* replacement character */ + } + } + + utf8_text = g_ucs4_to_utf8 ( + ucs4_text, + ucs4_length, + NULL, + output_length, + NULL + ); + g_free (ucs4_text); + + return utf8_text; +} +#endif + char * text_validate (char **text, int *len) { diff --git a/src/common/text.h b/src/common/text.h index 150821ae..6d5ac03e 100644 --- a/src/common/text.h +++ b/src/common/text.h @@ -28,6 +28,9 @@ int pevent_load (char *filename); void pevent_make_pntevts (void); void text_emit (int index, session *sess, char *a, char *b, char *c, char *d); int text_emit_by_name (char *name, session *sess, char *a, char *b, char *c, char *d); +#ifdef WIN32 +char *text_replace_non_bmp (char *utf8_input, int input_length, glong *output_length); +#endif char *text_validate (char **text, int *len); int get_stamp_str (char *fmt, time_t tim, char **ret); void format_event (session *sess, int index, char **args, char *o, int sizeofo, unsigned int stripcolor_args); diff --git a/src/common/thread.c b/src/common/thread.c new file mode 100644 index 00000000..02b17cfb --- /dev/null +++ b/src/common/thread.c @@ -0,0 +1,33 @@ +#include <fcntl.h> +#include "thread.h" + +thread * +thread_new (void) +{ + thread *th; + + th = calloc (1, sizeof (*th)); + if (!th) + { + return NULL; + } + + if (_pipe (th->pipe_fd, 4096, _O_BINARY) == -1) + { + free (th); + return NULL; + } + + return th; +} + +int +thread_start (thread *th, void *(*start_routine)(void *), void *arg) +{ + DWORD id; + + CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, (DWORD *)&id)); + th->threadid = id; + + return 1; +} diff --git a/src/common/thread.h b/src/common/thread.h new file mode 100644 index 00000000..7ca0f937 --- /dev/null +++ b/src/common/thread.h @@ -0,0 +1,10 @@ +#include <windows.h> + +typedef struct +{ + DWORD threadid; + int pipe_fd[2]; +} thread; + +thread *thread_new (void); +int thread_start (thread *th, void *(*start_routine)(void *), void *arg); diff --git a/src/common/url.c b/src/common/url.c index b83732d1..9fa2d75c 100644 --- a/src/common/url.c +++ b/src/common/url.c @@ -82,7 +82,7 @@ url_find (char *urltext) { int pos; - if (tree_find (url_tree, urltext, (tree_cmp_func *)strcasecmp, NULL, &pos)) + if (tree_find (url_tree, urltext, (tree_cmp_func *)g_ascii_strcasecmp, NULL, &pos)) return 1; return 0; } @@ -117,7 +117,7 @@ url_add (char *urltext, int len) } if (!url_tree) - url_tree = tree_new ((tree_cmp_func *)strcasecmp, NULL); + url_tree = tree_new ((tree_cmp_func *)g_ascii_strcasecmp, NULL); size = tree_size (url_tree); /* 0 is unlimited */ @@ -186,7 +186,7 @@ url_check_word (char *word, int len) { int j; - /* This is pretty much strncasecmp(). */ + /* This is pretty much g_ascii_strncasecmp(). */ for (j = 0; j < l; j++) { unsigned char c = word[j]; @@ -238,7 +238,7 @@ url_check_word (char *word, int len) const unsigned char *p = &word[len - l]; int j; - /* This is pretty much strncasecmp(). */ + /* This is pretty much g_ascii_strncasecmp(). */ for (j = 0; j < l; j++) { if (tolower(p[j]) != suffix[i].s[j]) diff --git a/src/common/util.c b/src/common/util.c index 5a0ab6c5..fb4cd23e 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -16,26 +16,32 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#define WANTSOCKET +#include "inet.h" /* make it first to avoid macro redefinitions */ + #define __APPLE_API_STRICT_CONFORMANCE #define _FILE_OFFSET_BITS 64 #include <stdio.h> -#include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> + #ifdef WIN32 #include <sys/timeb.h> #include <process.h> +#include <io.h> +#include "../dirent/dirent-win32.h" #else -#include <sys/types.h> +#include <unistd.h> #include <pwd.h> #include <sys/time.h> #include <sys/utsname.h> +#include <dirent.h> #endif + #include <fcntl.h> -#include <dirent.h> #include <errno.h> #include "xchat.h" #include "xchatc.h" @@ -44,9 +50,6 @@ #include "util.h" #include "../../config.h" -#define WANTSOCKET -#include "inet.h" - #if defined (USING_FREEBSD) || defined (__APPLE__) #include <sys/sysctl.h> #endif @@ -280,7 +283,7 @@ nocasestrstr (const char *s, const char *wanted) if (len == 0) return (char *)s; - while (rfc_tolower(*s) != rfc_tolower(*wanted) || strncasecmp (s, wanted, len)) + while (rfc_tolower(*s) != rfc_tolower(*wanted) || g_ascii_strncasecmp (s, wanted, len)) if (*s++ == '\0') return (char *)NULL; return (char *)s; @@ -383,6 +386,28 @@ waitline (int sok, char *buf, int bufsize, int use_recv) } } +#ifdef WIN32 +/* waitline2 using win32 file descriptor and glib instead of _read. win32 can't _read() sok! */ +int +waitline2 (GIOChannel *source, char *buf, int bufsize) +{ + int i = 0; + int len; + + while (1) + { + if (g_io_channel_read (source, &buf[i], 1, &len) != G_IO_ERROR_NONE) + return -1; + if (buf[i] == '\n' || bufsize == i + 1) + { + buf[i] = 0; + return i; + } + i++; + } +} +#endif + /* checks for "~" in a file and expands */ char * @@ -624,30 +649,110 @@ get_mhz (void) return 0; /* fails on Win9x */ } +int +get_cpu_arch (void) +{ + SYSTEM_INFO si; + + GetSystemInfo (&si); + + if (si.wProcessorArchitecture == 9) + { + return 64; + } + else + { + return 86; + } +} + char * get_cpu_str (void) { static char verbuf[64]; - OSVERSIONINFO osvi; - SYSTEM_INFO si; + static char winver[20]; + OSVERSIONINFOEX osvi; double mhz; - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); GetVersionEx (&osvi); - GetSystemInfo (&si); + + switch (osvi.dwMajorVersion) + { + case 5: + switch (osvi.dwMinorVersion) + { + case 1: + strcpy (winver, "XP"); + break; + case 2: + if (osvi.wProductType == VER_NT_WORKSTATION) + { + strcpy (winver, "XP x64 Edition"); + } + else + { + if (GetSystemMetrics(SM_SERVERR2) == 0) + { + strcpy (winver, "Server 2003"); + } + else + { + strcpy (winver, "Server 2003 R2"); + } + } + break; + } + break; + case 6: + switch (osvi.dwMinorVersion) + { + case 0: + if (osvi.wProductType == VER_NT_WORKSTATION) + { + strcpy (winver, "Vista"); + } + else + { + strcpy (winver, "Server 2008"); + } + break; + case 1: + if (osvi.wProductType == VER_NT_WORKSTATION) + { + strcpy (winver, "7"); + } + else + { + strcpy (winver, "Server 2008 R2"); + } + break; + case 2: + if (osvi.wProductType == VER_NT_WORKSTATION) + { + strcpy (winver, "8"); + } + else + { + strcpy (winver, "8 Server"); + } + break; + } + break; + } mhz = get_mhz (); if (mhz) { double cpuspeed = ( mhz > 1000 ) ? mhz / 1000 : mhz; const char *cpuspeedstr = ( mhz > 1000 ) ? "GHz" : "MHz"; - sprintf (verbuf, "Windows %ld.%ld [i%d86/%.2f%s]", - osvi.dwMajorVersion, osvi.dwMinorVersion, si.wProcessorLevel, - cpuspeed, cpuspeedstr); - } else - sprintf (verbuf, "Windows %ld.%ld [i%d86]", - osvi.dwMajorVersion, osvi.dwMinorVersion, si.wProcessorLevel); - + sprintf (verbuf, "Windows %s [%.2f%s]", winver, cpuspeed, cpuspeedstr); + } + else + { + sprintf (verbuf, "Windows %s", winver); + } + return verbuf; } @@ -840,7 +945,7 @@ typedef struct static int country_compare (const void *a, const void *b) { - return strcasecmp (a, ((domain_t *)b)->code); + return g_ascii_strcasecmp (a, ((domain_t *)b)->code); } static const domain_t domain[] = @@ -1727,3 +1832,55 @@ safe_strcpy (char *dest, const char *src, int bytes_left) } } } + +void +canonalize_key (char *key) +{ + char *pos, token; + + for (pos = key; (token = *pos) != 0; pos++) + { + if (token != '_' && (token < '0' || token > '9') && (token < 'A' || token > 'Z') && (token < 'a' || token > 'z')) + { + *pos = '_'; + } + else + { + *pos = tolower(token); + } + } +} + +int +portable_mode () +{ +#ifdef WIN32 + if ((_access( "portable-mode", 0 )) != -1) + { + return 1; + } + else + { + return 0; + } +#else + return 0; +#endif +} + +int +xtray_mode () +{ +#ifdef WIN32 + if ((_access( "plugins/xtray.dll", 0 )) != -1) + { + return 1; + } + else + { + return 0; + } +#else + return 0; +#endif +} diff --git a/src/common/util.h b/src/common/util.h index fce45def..82d74366 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -43,6 +43,12 @@ int strip_color2 (const char *src, int len, char *dst, int flags); int strip_hidden_attribute (char *src, char *dst); char *errorstring (int err); int waitline (int sok, char *buf, int bufsize, int); +#ifdef WIN32 +int waitline2 (GIOChannel *source, char *buf, int bufsize); +int get_cpu_arch (void); +#else +#define waitline2(source,buf,size) waitline(serv->childread,buf,size,0) +#endif unsigned long make_ping_time (void); void move_file_utf8 (char *src_dir, char *dst_dir, char *fname, int dccpermissions); int mkdir_utf8 (char *dir); @@ -50,5 +56,8 @@ int token_foreach (char *str, char sep, int (*callback) (char *str, void *ud), v guint32 str_hash (const char *key); guint32 str_ihash (const unsigned char *key); void safe_strcpy (char *dest, const char *src, int bytes_left); +void canonalize_key (char *key); +int portable_mode (); +int xtray_mode (); #endif diff --git a/src/common/xchat-plugin.h b/src/common/xchat-plugin.h index 30b19295..1b7da8fb 100644 --- a/src/common/xchat-plugin.h +++ b/src/common/xchat-plugin.h @@ -137,6 +137,21 @@ struct _xchat_plugin int flags); void (*xchat_free) (xchat_plugin *ph, void *ptr); + int (*xchat_pluginpref_set_str) (xchat_plugin *ph, + const char *var, + const char *value); + int (*xchat_pluginpref_get_str) (xchat_plugin *ph, + const char *var, + char *dest); + int (*xchat_pluginpref_set_int) (xchat_plugin *ph, + const char *var, + int value); + int (*xchat_pluginpref_get_int) (xchat_plugin *ph, + const char *var); + int (*xchat_pluginpref_delete) (xchat_plugin *ph, + const char *var); + int (*xchat_pluginpref_list) (xchat_plugin *ph, + char *dest); }; #endif @@ -292,6 +307,32 @@ void xchat_free (xchat_plugin *ph, void *ptr); +int +xchat_pluginpref_set_str (xchat_plugin *ph, + const char *var, + const char *value); + +int +xchat_pluginpref_get_str (xchat_plugin *ph, + const char *var, + char *dest); + +int +xchat_pluginpref_set_int (xchat_plugin *ph, + const char *var, + int value); +int +xchat_pluginpref_get_int (xchat_plugin *ph, + const char *var); + +int +xchat_pluginpref_delete (xchat_plugin *ph, + const char *var); + +int +xchat_pluginpref_list (xchat_plugin *ph, + char *dest); + #if !defined(PLUGIN_C) && defined(WIN32) #ifndef XCHAT_PLUGIN_HANDLE #define XCHAT_PLUGIN_HANDLE (ph) @@ -326,6 +367,12 @@ xchat_free (xchat_plugin *ph, #define xchat_send_modes ((XCHAT_PLUGIN_HANDLE)->xchat_send_modes) #define xchat_strip ((XCHAT_PLUGIN_HANDLE)->xchat_strip) #define xchat_free ((XCHAT_PLUGIN_HANDLE)->xchat_free) +#define xchat_pluginpref_set_str ((XCHAT_PLUGIN_HANDLE)->xchat_pluginpref_set_str) +#define xchat_pluginpref_get_str ((XCHAT_PLUGIN_HANDLE)->xchat_pluginpref_get_str) +#define xchat_pluginpref_set_int ((XCHAT_PLUGIN_HANDLE)->xchat_pluginpref_set_int) +#define xchat_pluginpref_get_int ((XCHAT_PLUGIN_HANDLE)->xchat_pluginpref_get_int) +#define xchat_pluginpref_delete ((XCHAT_PLUGIN_HANDLE)->xchat_pluginpref_delete) +#define xchat_pluginpref_list ((XCHAT_PLUGIN_HANDLE)->xchat_pluginpref_list) #endif #ifdef __cplusplus diff --git a/src/common/xchat.c b/src/common/xchat.c index afac9a0e..845f262b 100644 --- a/src/common/xchat.c +++ b/src/common/xchat.c @@ -22,14 +22,16 @@ #include <time.h> #include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> #define WANTSOCKET #include "inet.h" -#ifndef WIN32 +#ifdef WIN32 +#include <windows.h> +#else #include <sys/wait.h> #include <signal.h> +#include <unistd.h> #endif #include "xchat.h" @@ -590,6 +592,7 @@ static char defaultconf_commands[] = "NAME DMSG\n" "CMD msg =%2 &3\n\n"\ "NAME EXIT\n" "CMD quit\n\n"\ "NAME GREP\n" "CMD lastlog -r &2\n\n"\ + "NAME IGNALL\n" "CMD ignore %2!*@* ALL\n\n"\ "NAME J\n" "CMD join &2\n\n"\ "NAME KILL\n" "CMD quote KILL %2 :&3\n\n"\ "NAME LEAVE\n" "CMD part &2\n\n"\ @@ -899,11 +902,55 @@ xchat_execv (char * const argv[]) #endif } +#ifdef WIN32 +static void +xchat_restore_window (HWND xchat_window) +{ + /* ShowWindow (xchat_window, SW_RESTORE); another way, but works worse */ + SendMessage (xchat_window, WM_SYSCOMMAND, SC_RESTORE, 0); + SetForegroundWindow (xchat_window); +} + +BOOL CALLBACK +enum_windows_impl (HWND current_window, LPARAM lParam) +{ + TCHAR window_name[10]; + TCHAR module_path[1024]; + ZeroMemory (&window_name, sizeof (window_name)); + + if (!current_window) + { + return TRUE; + } + + GetWindowText (current_window, window_name, 10); + if (stricmp (window_name, "xchat-wdk") == 0) + { + /* use a separate if block, this way we don't have to call GetWindowModuleFileName() for each hit */ + ZeroMemory (&module_path, sizeof (module_path)); + GetWindowModuleFileName (current_window, module_path, sizeof (module_path)); + + if (strstr (module_path, "xchat.exe")) /* We've found it, stop */ + { + xchat_restore_window (current_window); + return FALSE; + } + } + + return TRUE; /* Keep searching */ + +} +#endif + int main (int argc, char *argv[]) { int ret; - + +#ifdef WIN32 + HANDLE mutex; +#endif + srand (time (0)); /* CL: do this only once! */ #ifdef SOCKS @@ -920,6 +967,34 @@ main (int argc, char *argv[]) load_config (); +#ifdef WIN32 + if (prefs.gui_one_instance && !portable_mode ()) + { + DWORD error; + + mutex = CreateMutex (NULL, TRUE, "Local\xchat"); + error = GetLastError (); + + if (error == ERROR_ALREADY_EXISTS || mutex == NULL) + { + /* restoring the XChat window from the tray via the taskbar icon + * only works correctly when X-Tray is used, but it's not a big deal + * since you can only minimize XChat to tray via the taskbar if you + * use X-Tray*/ + if (xtray_mode ()) + { + /* FindWindow() doesn't support wildcards so we check all the open windows */ + EnumWindows (enum_windows_impl, NULL); + return 0; + } + else + { + return 1; + } + } + } +#endif + #ifdef USE_LIBPROXY libproxy_factory = px_proxy_factory_new(); #endif @@ -945,6 +1020,11 @@ main (int argc, char *argv[]) #ifdef WIN32 WSACleanup (); + + if (prefs.gui_one_instance && !portable_mode ()) + { + CloseHandle (mutex); + } #endif return 0; diff --git a/src/common/xchat.h b/src/common/xchat.h index 6e31d7c5..85c20186 100644 --- a/src/common/xchat.h +++ b/src/common/xchat.h @@ -13,7 +13,7 @@ #endif #ifndef HAVE_VSNPRINTF -#define vsnprintf g_vsnprintf +#define vsnprintf _vsnprintf #endif #ifdef USE_DEBUG @@ -41,8 +41,8 @@ void *xchat_realloc (char *old, int len, char *file, int line); #ifdef __EMX__ /* for o/s 2 */ #define OFLAGS O_BINARY -#define strcasecmp stricmp -#define strncasecmp strnicmp +#define g_ascii_strcasecmp stricmp +#define g_ascii_strncasecmp strnicmp #define PATH_MAX MAXPATHLEN #define FILEPATH_LEN_MAX MAXPATHLEN #endif @@ -54,7 +54,7 @@ void *xchat_realloc (char *old, int len, char *file, int line); #ifdef WIN32 /* for win32 */ #define OFLAGS O_BINARY -#define sleep(t) _sleep(t*1000) +#define sleep(t) Sleep(t*1000) #include <direct.h> #define F_OK 0 #define X_OK 1 @@ -113,8 +113,16 @@ struct xchatprefs char awayreason[256]; char quitreason[256]; char partreason[256]; +#ifdef WIN32 + char font_normal[4 * FONTNAMELEN + 1]; + char font_main[FONTNAMELEN + 1]; + char font_alternative[3 * FONTNAMELEN + 1]; +#else char font_normal[FONTNAMELEN + 1]; +#endif char doubleclickuser[256]; + char gui_license[64]; + char spell_langs[64]; char sounddir[PATHLEN + 1]; char soundcmd[PATHLEN + 1]; char background[PATHLEN + 1]; @@ -152,6 +160,7 @@ struct xchatprefs int gui_pane_left_size; int gui_pane_right_size; + int gui_pane_right_size_min; int gui_ulist_pos; int tab_pos; @@ -178,6 +187,9 @@ struct xchatprefs int gui_usermenu; int gui_join_dialog; int gui_quit_dialog; +#ifdef WIN32 + int gui_one_instance; +#endif int dialog_left; int dialog_top; int dialog_width; @@ -205,6 +217,9 @@ struct xchatprefs unsigned int wallops; unsigned int skipmotd; unsigned int autorejoin; + unsigned int autocopy_text; + unsigned int autocopy_stamp; + unsigned int autocopy_color; unsigned int colorednicks; unsigned int chanmodebuttons; unsigned int userlistbuttons; @@ -292,7 +307,12 @@ struct xchatprefs unsigned int wait_on_exit; unsigned int confmode; unsigned int utf8_locale; +#ifdef WIN32 unsigned int identd; + unsigned int emoticons; + unsigned int tab_icons; + unsigned int tab_xp; +#endif unsigned int ctcp_number_limit; /*flood */ unsigned int ctcp_time_limit; /*seconds of floods */ @@ -306,6 +326,11 @@ struct xchatprefs This is so that we continue using internal defaults (which can change in the next release) until the user edits them. */ unsigned int save_pevents:1; + unsigned int text_search_case_match; + unsigned int text_search_backward; + unsigned int text_search_highlight_all; + unsigned int text_search_follow; + unsigned int text_search_regexp; }; /* Session types */ |