/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include #include #include "xchat.h" #include "cfgfiles.h" #include "util.h" #include "fe.h" #include "text.h" #include "xchatc.h" #ifndef WIN32 #include #define HEXCHAT_DIR "hexchat" #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) { struct popup *pop; int cmd_len = 1, name_len; /* remove <2.8.0 stuff */ if (!strcmp (cmd, "away") && !strcmp (name, "BACK")) return; if (cmd) cmd_len = strlen (cmd) + 1; name_len = strlen (name) + 1; pop = malloc (sizeof (struct popup) + cmd_len + name_len); pop->name = (char *) pop + sizeof (struct popup); pop->cmd = pop->name + name_len; memcpy (pop->name, name, name_len); if (cmd) memcpy (pop->cmd, cmd, cmd_len); else pop->cmd[0] = 0; *list = g_slist_append (*list, pop); } /* read it in from a buffer to our linked list */ static void list_load_from_data (GSList ** list, char *ibuf, int size) { char cmd[384]; char name[128]; char *buf; int pnt = 0; cmd[0] = 0; name[0] = 0; while (buf_get_line (ibuf, &buf, &pnt, size)) { if (*buf != '#') { if (!g_ascii_strncasecmp (buf, "NAME ", 5)) { safe_strcpy (name, buf + 5, sizeof (name)); } else if (!g_ascii_strncasecmp (buf, "CMD ", 4)) { safe_strcpy (cmd, buf + 4, sizeof (cmd)); if (*name) { list_addentry (list, cmd, name); cmd[0] = 0; name[0] = 0; } } } } } void list_loadconf (char *file, GSList ** list, char *defaultconf) { char filebuf[256]; char *ibuf; int fh; struct stat st; snprintf (filebuf, sizeof (filebuf), "%s/%s", get_xdir_fs (), file); fh = open (filebuf, O_RDONLY | OFLAGS); if (fh == -1) { if (defaultconf) list_load_from_data (list, defaultconf, strlen (defaultconf)); return; } if (fstat (fh, &st) != 0) { perror ("fstat"); abort (); } ibuf = malloc (st.st_size); read (fh, ibuf, st.st_size); close (fh); list_load_from_data (list, ibuf, st.st_size); free (ibuf); } void list_free (GSList ** list) { void *data; while (*list) { data = (void *) (*list)->data; free (data); *list = g_slist_remove (*list, data); } } int list_delentry (GSList ** list, char *name) { struct popup *pop; GSList *alist = *list; while (alist) { pop = (struct popup *) alist->data; if (!g_ascii_strcasecmp (name, pop->name)) { *list = g_slist_remove (*list, pop); free (pop); return 1; } alist = alist->next; } return 0; } 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 (!g_ascii_strncasecmp (buffer, cfg, strlen (var) + 1)) { char *value, t; cfg += strlen (var); while (*cfg == ' ') cfg++; if (*cfg == '=') cfg++; while (*cfg == ' ') cfg++; /*while (*cfg == ' ' || *cfg == '=') cfg++; */ value = cfg; while (*cfg != 0 && *cfg != '\n') cfg++; t = *cfg; *cfg = 0; safe_strcpy (dest, value, dest_len); *cfg = t; return cfg; } while (*cfg != 0 && *cfg != '\n') cfg++; if (*cfg == 0) return 0; cfg++; if (*cfg == 0) return 0; } } static int cfg_put_str (int fh, char *var, char *value) { char buf[512]; int len; snprintf (buf, sizeof buf, "%s = %s\n", var, value); len = strlen (buf); return (write (fh, buf, len) == len); } int cfg_put_color (int fh, int r, int g, int b, char *var) { char buf[400]; int len; snprintf (buf, sizeof buf, "%s = %04x %04x %04x\n", var, r, g, b); len = strlen (buf); return (write (fh, buf, len) == len); } int cfg_put_int (int fh, int value, char *var) { char buf[400]; int len; if (value == -1) value = 1; snprintf (buf, sizeof buf, "%s = %d\n", var, value); len = strlen (buf); return (write (fh, buf, len) == len); } int cfg_get_color (char *cfg, char *var, int *r, int *g, int *b) { char str[128]; if (!cfg_get_str (cfg, var, str, sizeof (str))) return 0; sscanf (str, "%04x %04x %04x", r, g, b); return 1; } int cfg_get_int_with_result (char *cfg, char *var, int *result) { char str[128]; if (!cfg_get_str (cfg, var, str, sizeof (str))) { *result = 0; return 0; } *result = 1; return atoi (str); } int cfg_get_int (char *cfg, char *var) { char str[128];
/*

  Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

#ifndef KEYSTORE_H
#define KEYSTORE_H

#ifdef _MSC_VER
#include "bool.h"
#else
#include <stdbool.h>
#endif
#include <stddef.h>

char *keystore_get_key(const char *nick);
bool keystore_store_key(const char *nick, const char *key);
bool keystore_delete_nick(const char *nick);

void keystore_secure_free(void *ptr, size_t size);

#endif
FINT (userhost), TYPE_BOOL}, {"irc_whois_front", P_OFFINT (irc_whois_front), TYPE_BOOL}, {"net_auto_reconnect", P_OFFINT (autoreconnect), TYPE_BOOL}, {"net_auto_reconnectonfail", P_OFFINT (autoreconnectonfail), TYPE_BOOL}, {"net_bind_host", P_OFFSET (hostname), TYPE_STR}, {"net_ping_timeout", P_OFFINT (pingtimeout), TYPE_INT}, {"net_proxy_auth", P_OFFINT (proxy_auth), TYPE_BOOL}, {"net_proxy_host", P_OFFSET (proxy_host), TYPE_STR}, {"net_proxy_pass", P_OFFSET (proxy_pass), TYPE_STR}, {"net_proxy_port", P_OFFINT (proxy_port), TYPE_INT}, {"net_proxy_type", P_OFFINT (proxy_type), TYPE_INT}, {"net_proxy_use", P_OFFINT (proxy_use), TYPE_INT}, {"net_proxy_user", P_OFFSET (proxy_user), TYPE_STR}, {"net_reconnect_delay", P_OFFINT (recon_delay), TYPE_INT}, {"net_throttle", P_OFFINT (throttle), TYPE_BOOL}, {"notify_timeout", P_OFFINT (notify_timeout), TYPE_INT}, {"notify_whois_online", P_OFFINT (whois_on_notifyonline), TYPE_BOOL}, {"perl_warnings", P_OFFINT (perlwarnings), TYPE_BOOL}, {"sound_command", P_OFFSET (soundcmd), TYPE_STR}, {"sound_dir", P_OFFSET (sounddir), TYPE_STR}, {"stamp_log", P_OFFINT (timestamp_logs), TYPE_BOOL}, {"stamp_log_format", P_OFFSET (timestamp_log_format), TYPE_STR}, {"stamp_text", P_OFFINT (timestamp), TYPE_BOOL}, {"stamp_text_format", P_OFFSET (stamp_format), TYPE_STR}, {"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}, {"tab_pos", P_OFFINT (tab_pos), TYPE_INT}, {"tab_position", P_OFFINT (_tabs_position), TYPE_INT}, /* obsolete */ {"tab_server", P_OFFINT (use_server_tab), TYPE_BOOL}, {"tab_small", P_OFFINT (tab_small), TYPE_INT}, {"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}, {"text_tint_green", P_OFFINT (tint_green), TYPE_INT}, {"text_tint_red", P_OFFINT (tint_red), TYPE_INT}, {"text_transparent", P_OFFINT (transparent), TYPE_BOOL}, {"text_wordwrap", P_OFFINT (wordwrap), TYPE_BOOL}, {"url_grabber", P_OFFINT (url_grabber), TYPE_BOOL}, {"url_grabber_limit", P_OFFINT (url_grabber_limit), TYPE_INT}, {0, 0, 0}, }; static char * convert_with_fallback (const char *str, const char *fallback) { char *utf; utf = g_locale_to_utf8 (str, -1, 0, 0, 0); if (!utf) { /* this can happen if CHARSET envvar is set wrong */ /* maybe it's already utf8 (breakage!) */ if (!g_utf8_validate (str, -1, NULL)) utf = g_strdup (fallback); else utf = g_strdup (str); } return utf; } void load_config (void) { struct stat st; char *cfg, *sp; const char *username, *realname; int res, val, i, fh; check_prefs_dir (); username = g_get_user_name (); if (!username) username = "root"; /* 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 = "realname"; username = convert_with_fallback (username, "username"); realname = convert_with_fallback (realname, "realname"); memset (&prefs, 0, sizeof (struct xchatprefs)); /* put in default values, anything left out is automatically zero */ prefs.local_ip = 0xffffffff; prefs.irc_join_delay = 3; prefs.show_marker = 1; prefs.newtabstofront = 2; prefs.completion_amount = 5; prefs.away_timeout = 60; prefs.away_size_max = 300; prefs.away_track = 1; prefs.timestamp_logs = 1; prefs.truncchans = 20; prefs.autoresume = 1; prefs.show_away_once = 1; 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 */ prefs.tab_sort = 1; prefs.paned_userlist = 1; prefs.newtabstofront = 2; prefs.use_server_tab = 1; prefs.privmsgtab = 1; /*prefs.style_inputbox = 1;*/ prefs.dccpermissions = 0600; prefs.max_lines = 500; prefs.mainwindow_width = 640; prefs.mainwindow_height = 400; prefs.dialog_width = 500; prefs.dialog_height = 256; prefs.gui_join_dialog = 1; prefs.gui_quit_dialog = 1; prefs.dcctimeout = 180; prefs.dccstalltimeout = 60; prefs.notify_timeout = 15; prefs.tint_red = prefs.tint_green = prefs.tint_blue = 195; prefs.auto_indent = 1; prefs.max_auto_indent = 256; prefs.show_separator = 1; prefs.dcc_blocksize = 1024; prefs.throttle = 1; /*FIXME*/ prefs.msg_time_limit = 30; prefs.msg_number_limit = 5; prefs.ctcp_time_limit = 30; prefs.ctcp_number_limit = 5; prefs.topicbar = 1; prefs.lagometer = 1; prefs.throttlemeter = 1; prefs.autoopendccrecvwindow = 1; prefs.autoopendccsendwindow = 1; prefs.autoopendccchatwindow = 1; prefs.userhost = 1; prefs.gui_url_mod = 4; /* ctrl */ 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; prefs.input_flash_priv = prefs.input_flash_hilight = 1; prefs.input_tray_priv = prefs.input_tray_hilight = 1; 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.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"); strcpy (prefs.nick_suffix, ","); strcpy (prefs.cmdchar, "/"); strcpy (prefs.nick1, username); strcpy (prefs.nick2, username); strcat (prefs.nick2, "_"); strcpy (prefs.nick3, username); strcat (prefs.nick3, "__"); strcpy (prefs.realname, realname); strcpy (prefs.username, username); #ifdef WIN32 strcpy (prefs.sounddir, "./sounds"); { char out[256]; if (get_reg_str ("Software\\Microsoft\\Windows\\CurrentVersion\\" "Explorer\\Shell Folders", "Personal", out, sizeof (out))) snprintf (prefs.dccdir, sizeof (prefs.dccdir), "%s\\Downloads", out); else snprintf (prefs.dccdir, sizeof (prefs.dccdir), "%s\\Downloads", get_xdir_utf8 ()); } #else snprintf (prefs.sounddir, sizeof (prefs.sounddir), "%s/sounds", get_xdir_utf8 ()); snprintf (prefs.dccdir, sizeof (prefs.dccdir), "%s/downloads", get_xdir_utf8 ()); #endif strcpy (prefs.doubleclickuser, "QUOTE WHOIS %s %s"); strcpy (prefs.awayreason, _("I'm busy")); 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"); g_free ((char *)username); g_free ((char *)realname); fh = open (default_file (), OFLAGS | O_RDONLY); if (fh != -1) { fstat (fh, &st); cfg = malloc (st.st_size + 1); cfg[0] = '\0'; i = read (fh, cfg, st.st_size); if (i >= 0) cfg[i] = '\0'; /* make sure cfg is NULL terminated */ close (fh); i = 0; do { switch (vars[i].type) { case TYPE_STR: cfg_get_str (cfg, vars[i].name, (char *) &prefs + vars[i].offset, vars[i].len); break; case TYPE_BOOL: case TYPE_INT: val = cfg_get_int_with_result (cfg, vars[i].name, &res); if (res) *((int *) &prefs + vars[i].offset) = val; break; } i++; } while (vars[i].name); free (cfg); } else { #ifndef WIN32 #ifndef __EMX__ /* OS/2 uses UID 0 all the time */ if (getuid () == 0) fe_message (_("* Running IRC as root is stupid! You should\n" " create a User Account and use that to login.\n"), FE_MSG_WARN|FE_MSG_WAIT); #endif #endif /* !WIN32 */ mkdir_utf8 (prefs.dccdir); mkdir_utf8 (prefs.dcc_completed_dir); } if (prefs.mainwindow_height < 138) prefs.mainwindow_height = 138; if (prefs.mainwindow_width < 106) prefs.mainwindow_width = 106; sp = strchr (prefs.username, ' '); if (sp) sp[0] = 0; /* spaces in username would break the login */ /* try to make sense of old ulist/tree position settings */ if (prefs.gui_ulist_pos == 0) { prefs.gui_ulist_pos = 3; /* top right */ if (prefs._gui_ulist_left) prefs.gui_ulist_pos = 2; /* bottom left */ switch (prefs._tabs_position) { case 0: prefs.tab_pos = 6; /* bottom */ break; case 1: prefs.tab_pos = 5; /* top */ break; case 2: prefs.tab_pos = 1; /* left */ break; case 3: prefs.tab_pos = 4; /* right */ break; case 4: prefs.tab_pos = 1; /* (hidden)left */ break; case 5: if (prefs._gui_ulist_left) { prefs.tab_pos = 1; /* above ulist left */ prefs.gui_ulist_pos = 2; } else { prefs.tab_pos = 3; /* above ulist right */ prefs.gui_ulist_pos = 4; } break; } } } int save_config (void) { int fh, i; char *new_config, *config; check_prefs_dir (); config = default_file (); new_config = malloc (strlen (config) + 5); strcpy (new_config, config); strcat (new_config, ".new"); fh = open (new_config, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT, 0600); if (fh == -1) { free (new_config); return 0; } if (!cfg_put_str (fh, "version", PACKAGE_VERSION)) { free (new_config); return 0; } i = 0; do { switch (vars[i].type) { case TYPE_STR: if (!cfg_put_str (fh, vars[i].name, (char *) &prefs + vars[i].offset)) { free (new_config); return 0; } break; case TYPE_INT: case TYPE_BOOL: if (!cfg_put_int (fh, *((int *) &prefs + vars[i].offset), vars[i].name)) { free (new_config); return 0; } } i++; } while (vars[i].name); if (close (fh) == -1) { free (new_config); return 0; } #ifdef WIN32 unlink (config); /* win32 can't rename to an existing file */ #endif if (rename (new_config, config) == -1) { free (new_config); return 0; } free (new_config); return 1; } static void set_showval (session *sess, const struct prefs *var, char *tbuf) { int len, dots, j; len = strlen (var->name); memcpy (tbuf, var->name, len); dots = 29 - len; if (dots < 0) dots = 0; tbuf[len++] = '\003'; tbuf[len++] = '2'; for (j=0;jtype) { case TYPE_STR: sprintf (tbuf + len, "\0033:\017 %s\n", (char *) &prefs + var->offset); break; case TYPE_INT: sprintf (tbuf + len, "\0033:\017 %d\n", *((int *) &prefs + var->offset)); break; case TYPE_BOOL: if (*((int *) &prefs + var->offset)) sprintf (tbuf + len, "\0033:\017 %s\n", "ON"); else sprintf (tbuf + len, "\0033:\017 %s\n", "OFF"); break; } PrintText (sess, tbuf); } static void set_list (session * sess, char *tbuf) { int i; i = 0; do { set_showval (sess, &vars[i], tbuf); i++; } while (vars[i].name); } int cfg_get_bool (char *var) { int i = 0; do { if (!g_ascii_strcasecmp (var, vars[i].name)) { return *((int *) &prefs + vars[i].offset); } i++; } while (vars[i].name); return -1; } int cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { int wild = FALSE; int or = FALSE; int off = FALSE; int quiet = FALSE; int erase = FALSE; int i = 0, finds = 0, found; int idx = 2; char *var, *val; if (g_ascii_strcasecmp (word[2], "-e") == 0) { idx++; erase = TRUE; } /* turn a bit OFF */ if (g_ascii_strcasecmp (word[idx], "-off") == 0) { idx++; off = TRUE; } /* turn a bit ON */ if (g_ascii_strcasecmp (word[idx], "-or") == 0 || g_ascii_strcasecmp (word[idx], "-on") == 0) { idx++; or = TRUE; } if (g_ascii_strcasecmp (word[idx], "-quiet") == 0) { idx++; quiet = TRUE; } var = word[idx]; val = word_eol[idx+1]; if (!*var) { set_list (sess, tbuf); return TRUE; } if ((strchr (var, '*') || strchr (var, '?')) && !*val) wild = TRUE; if (*val == '=') val++; do { if (wild) found = !match (var, vars[i].name); else found = g_ascii_strcasecmp (var, vars[i].name); if (found == 0) { finds++; switch (vars[i].type) { case TYPE_STR: if (erase || *val) { strncpy ((char *) &prefs + vars[i].offset, val, vars[i].len); ((char *) &prefs)[vars[i].offset + vars[i].len - 1] = 0; if (!quiet) PrintTextf (sess, "%s set to: %s\n", var, (char *) &prefs + vars[i].offset); } else { set_showval (sess, &vars[i], tbuf); } break; case TYPE_INT: case TYPE_BOOL: if (*val) { if (vars[i].type == TYPE_BOOL) { if (atoi (val)) *((int *) &prefs + vars[i].offset) = 1; else *((int *) &prefs + vars[i].offset) = 0; if (!g_ascii_strcasecmp (val, "YES") || !g_ascii_strcasecmp (val, "ON")) *((int *) &prefs + vars[i].offset) = 1; if (!g_ascii_strcasecmp (val, "NO") || !g_ascii_strcasecmp (val, "OFF")) *((int *) &prefs + vars[i].offset) = 0; } else { if (or) *((int *) &prefs + vars[i].offset) |= atoi (val); else if (off) *((int *) &prefs + vars[i].offset) &= ~(atoi (val)); else *((int *) &prefs + vars[i].offset) = atoi (val); } if (!quiet) PrintTextf (sess, "%s set to: %d\n", var, *((int *) &prefs + vars[i].offset)); } else { set_showval (sess, &vars[i], tbuf); } break; } } i++; } 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; } int xchat_open_file (char *file, int flags, int mode, int xof_flags) { char buf[1024]; if (xof_flags & XOF_FULLPATH) { if (xof_flags & XOF_DOMODE) return open (file, flags | OFLAGS, mode); else return open (file, flags | OFLAGS); } snprintf (buf, sizeof (buf), "%s/%s", get_xdir_fs (), file); if (xof_flags & XOF_DOMODE) return open (buf, flags | OFLAGS, mode); else return open (buf, flags | OFLAGS); } FILE * xchat_fopen_file (const char *file, const char *mode, int xof_flags) { char buf[1024]; if (xof_flags & XOF_FULLPATH) return fopen (file, mode); snprintf (buf, sizeof (buf), "%s/%s", get_xdir_fs (), file); return fopen (buf, mode); }