summary refs log tree commit diff stats
path: root/src/common
diff options
context:
space:
mode:
authorTingPing <tngpng@gmail.com>2013-05-24 15:01:27 -0700
committerTingPing <tngpng@gmail.com>2013-05-24 15:01:27 -0700
commit270cde42f1f801060b4f733d7f70ab37413024d4 (patch)
tree11220c510c9201bcfc82ed6711b4a179fed1bde2 /src/common
parentb690098941613261c5c1cc8cdb7e92ef0cc6871b (diff)
parentd9d05e83ba9975959607302c45a631ee80a2d21e (diff)
Merge pull request #590 from orium/run-as-root-589-504
Now hexchat doesn't abnormally terminate when started as root.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/cfgfiles.c140
-rw-r--r--src/common/cfgfiles.h6
-rw-r--r--src/common/hexchat.c217
3 files changed, 132 insertions, 231 deletions
diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c
index c3cad2aa..20e48ffd 100644
--- a/src/common/cfgfiles.c
+++ b/src/common/cfgfiles.c
@@ -337,21 +337,10 @@ get_xdir (void)
 	return xdir;
 }
 
-static void
-check_prefs_dir (void)
+int
+check_config_dir (void)
 {
-	char *dir = get_xdir ();
-	char *msg;
-
-	if (g_access (dir, F_OK) != 0)
-	{
-		if (g_mkdir (dir, 0700) != 0)
-		{
-			msg = g_strdup_printf ("Cannot create %s", get_xdir ());
-			fe_message (msg, FE_MSG_ERROR);
-			g_free (msg);
-		}
-	}
+	return g_access (get_xdir (), F_OK);
 }
 
 static char *
@@ -617,16 +606,14 @@ convert_with_fallback (const char *str, const char *fallback)
 }
 
 void
-load_config (void)
+load_default_config(void)
 {
-	char *cfg, *sp, *buf;
 	const char *username, *realname;
-	int res, val, i;
+	char *sp;
 #ifdef WIN32
 	char out[256];
 #endif
 
-	check_prefs_dir ();
 	username = g_get_user_name ();
 	if (!username)
 		username = "root";
@@ -800,55 +787,89 @@ load_config (void)
 	/* private variables */
 	prefs.local_ip = 0xffffffff;
 
+	sp = strchr (prefs.hex_irc_user_name, ' ');
+	if (sp)
+		sp[0] = 0;	/* spaces in username would break the login */
+
 	g_free ((char *)username);
 	g_free ((char *)realname);
+}
 
-	if (g_file_get_contents (default_file (), &cfg, NULL, NULL))
+int
+make_config_dirs (void)
+{
+	char *buf;
+
+	if (g_mkdir (get_xdir (), 0700) != 0)
+		return -1;
+	
+	buf = g_build_filename (get_xdir (), "addons", NULL);
+	if (g_mkdir (buf, 0700) != 0)
 	{
-		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);
+		g_free (buf);
+		return -1;
+	}
+	g_free (buf);
+	
+	buf = g_build_filename (get_xdir (), HEXCHAT_SOUND_DIR, NULL);
+	if (g_mkdir (buf, 0700) != 0)
+	{
+		g_free (buf);
+		return -1;
+	}
+	g_free (buf);
 
-		g_free (cfg);
+	return 0;
+}
 
-	} 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 */
+int
+make_dcc_dirs (void)
+{
+	if (g_mkdir (prefs.hex_dcc_dir, 0700) != 0)
+		return -1;
 
-		g_mkdir (prefs.hex_dcc_dir, 0700);
-		g_mkdir (prefs.hex_dcc_completed_dir, 0700);
+	if (g_mkdir (prefs.hex_dcc_completed_dir, 0700) != 0)
+		return -1;
 
-		buf = g_build_filename (get_xdir (), "addons", NULL);
-		g_mkdir (buf, 0700);
-		g_free (buf);
+	return 0;
+}
 
-		buf = g_build_filename (get_xdir (), HEXCHAT_SOUND_DIR, NULL);
-		g_mkdir (buf, 0700);
-		g_free (buf);
+int
+load_config (void)
+{
+	char *cfg, *sp;
+	int res, val, i;
+
+	g_assert(check_config_dir () == 0);
+
+	if (!g_file_get_contents (default_file (), &cfg, NULL, NULL))
+		return -1;
+
+	/* If the config is incomplete we have the default values loaded */
+	load_default_config();
+
+	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);
+	
+	g_free (cfg);
+
 	if (prefs.hex_gui_win_height < 138)
 		prefs.hex_gui_win_height = 138;
 	if (prefs.hex_gui_win_width < 106)
@@ -857,6 +878,8 @@ load_config (void)
 	sp = strchr (prefs.hex_irc_user_name, ' ');
 	if (sp)
 		sp[0] = 0;	/* spaces in username would break the login */
+
+	return 0;
 }
 
 int
@@ -865,7 +888,8 @@ save_config (void)
 	int fh, i;
 	char *config, *new_config;
 
-	check_prefs_dir ();
+	if (check_config_dir () != 0)
+		make_config_dirs ();
 
 	config = default_file ();
 	new_config = g_strconcat (config, ".new", NULL);
diff --git a/src/common/cfgfiles.h b/src/common/cfgfiles.h
index 103466f3..3a59d26d 100644
--- a/src/common/cfgfiles.h
+++ b/src/common/cfgfiles.h
@@ -34,7 +34,11 @@ int cfg_put_int (int fh, int value, char *var);
 int cfg_get_color (char *cfg, char *var, int *r, int *g, int *b);
 int cfg_put_color (int fh, int r, int g, int b, char *var);
 char *get_xdir (void);
-void load_config (void);
+int check_config_dir (void);
+void load_default_config (void);
+int make_config_dirs (void);
+int make_dcc_dirs (void);
+int load_config (void);
 int save_config (void);
 void list_free (GSList ** list);
 void list_loadconf (char *file, GSList ** list, char *defaultconf);
diff --git a/src/common/hexchat.c b/src/common/hexchat.c
index c879af9d..aa37b850 100644
--- a/src/common/hexchat.c
+++ b/src/common/hexchat.c
@@ -1014,16 +1014,37 @@ hexchat_execv (char * const argv[])
 #endif
 }
 
+static void
+set_locale (void)
+{
+#ifdef WIN32
+	const char const *langs[]={
+		"af", "sq", "am", "ast", "az", "eu", "be", "bg", "ca", "zh_CN",   /* 0 .. 9   */
+		"zh_TW", "cs", "da", "nl", "en_GB", "en", "et", "fi", "fr", "gl", /* 10 .. 19 */
+		"de", "el", "gu", "hi", "hu", "id", "it", "ja", "kn", "rw",       /* 20 .. 29 */
+		"ko", "lv", "lt", "mk", "ml", "ms", "nb", "no", "pl", "pt",       /* 30 .. 39 */
+		"pt_BR", "pa", "ru", "sr", "sk", "sl", "es", "sv", "th", "uk",    /* 40 .. 49 */
+		"vi", "wa"                                                        /* 50 .. */
+	};
+	char hexchat_lang[13];	/* LC_ALL= plus 5 chars of hex_gui_lang and trailing \0 */
+
+	strcpy (hexchat_lang, "LC_ALL=");
+
+	if (0 <= prefs.hex_gui_lang && prefs.hex_gui_lang < sizeof(langs)/sizeof(*langs))
+		strcat (hexchat_lang, langs[prefs.hex_gui_lang]);
+	else
+		strcat (hexchat_lang, "en");
+
+	putenv (hexchat_lang);
+#endif
+}
+
 int
 main (int argc, char *argv[])
 {
 	int i;
 	int ret;
 
-#ifdef WIN32
-	char hexchat_lang[13];	/* LC_ALL= plus 5 chars of hex_gui_lang and trailing \0 */
-#endif
-
 	srand (time (0));	/* CL: do this only once! */
 
 	/* We must check for the config dir parameter, otherwise load_config() will behave incorrectly.
@@ -1054,178 +1075,21 @@ main (int argc, char *argv[])
 #if ! GLIB_CHECK_VERSION (2, 36, 0)
 	g_type_init ();
 #endif
-	load_config ();
 
-#ifdef WIN32
-	/* we MUST do this after load_config () AND before fe_init (thus gtk_init) otherwise it will fail */
-	strcpy (hexchat_lang, "LC_ALL=");
-
-	/* this must be ordered EXACTLY as langsmenu[] */
-	switch (prefs.hex_gui_lang)
+	if (check_config_dir () == 0)
+	{
+		if (load_config () != 0)
+			load_default_config ();
+	} else
 	{
-		case 0:
-			strcat (hexchat_lang, "af");
-			break;
-		case 1:
-			strcat (hexchat_lang, "sq");
-			break;
-		case 2:
-			strcat (hexchat_lang, "am");
-			break;
-		case 3:
-			strcat (hexchat_lang, "ast");
-			break;
-		case 4:
-			strcat (hexchat_lang, "az");
-			break;
-		case 5:
-			strcat (hexchat_lang, "eu");
-			break;
-		case 6:
-			strcat (hexchat_lang, "be");
-			break;
-		case 7:
-			strcat (hexchat_lang, "bg");
-			break;
-		case 8:
-			strcat (hexchat_lang, "ca");
-			break;
-		case 9:
-			strcat (hexchat_lang, "zh_CN");
-			break;
-		case 10:
-			strcat (hexchat_lang, "zh_TW");
-			break;
-		case 11:
-			strcat (hexchat_lang, "cs");
-			break;
-		case 12:
-			strcat (hexchat_lang, "da");
-			break;
-		case 13:
-			strcat (hexchat_lang, "nl");
-			break;
-		case 14:
-			strcat (hexchat_lang, "en_GB");
-			break;
-		case 15:
-			strcat (hexchat_lang, "en");
-			break;
-		case 16:
-			strcat (hexchat_lang, "et");
-			break;
-		case 17:
-			strcat (hexchat_lang, "fi");
-			break;
-		case 18:
-			strcat (hexchat_lang, "fr");
-			break;
-		case 19:
-			strcat (hexchat_lang, "gl");
-			break;
-		case 20:
-			strcat (hexchat_lang, "de");
-			break;
-		case 21:
-			strcat (hexchat_lang, "el");
-			break;
-		case 22:
-			strcat (hexchat_lang, "gu");
-			break;
-		case 23:
-			strcat (hexchat_lang, "hi");
-			break;
-		case 24:
-			strcat (hexchat_lang, "hu");
-			break;
-		case 25:
-			strcat (hexchat_lang, "id");
-			break;
-		case 26:
-			strcat (hexchat_lang, "it");
-			break;
-		case 27:
-			strcat (hexchat_lang, "ja");
-			break;
-		case 28:
-			strcat (hexchat_lang, "kn");
-			break;
-		case 29:
-			strcat (hexchat_lang, "rw");
-			break;
-		case 30:
-			strcat (hexchat_lang, "ko");
-			break;
-		case 31:
-			strcat (hexchat_lang, "lv");
-			break;
-		case 32:
-			strcat (hexchat_lang, "lt");
-			break;
-		case 33:
-			strcat (hexchat_lang, "mk");
-			break;
-		case 34:
-			strcat (hexchat_lang, "ml");
-			break;
-		case 35:
-			strcat (hexchat_lang, "ms");
-			break;
-		case 36:
-			strcat (hexchat_lang, "nb");
-			break;
-		case 37:
-			strcat (hexchat_lang, "no");
-			break;
-		case 38:
-			strcat (hexchat_lang, "pl");
-			break;
-		case 39:
-			strcat (hexchat_lang, "pt");
-			break;
-		case 40:
-			strcat (hexchat_lang, "pt_BR");
-			break;
-		case 41:
-			strcat (hexchat_lang, "pa");
-			break;
-		case 42:
-			strcat (hexchat_lang, "ru");
-			break;
-		case 43:
-			strcat (hexchat_lang, "sr");
-			break;
-		case 44:
-			strcat (hexchat_lang, "sk");
-			break;
-		case 45:
-			strcat (hexchat_lang, "sl");
-			break;
-		case 46:
-			strcat (hexchat_lang, "es");
-			break;
-		case 47:
-			strcat (hexchat_lang, "sv");
-			break;
-		case 48:
-			strcat (hexchat_lang, "th");
-			break;
-		case 49:
-			strcat (hexchat_lang, "uk");
-			break;
-		case 50:
-			strcat (hexchat_lang, "vi");
-			break;
-		case 51:
-			strcat (hexchat_lang, "wa");
-			break;
-		default:
-			strcat (hexchat_lang, "en");
-			break;
+		/* this is probably the first run */
+		load_default_config ();
+		make_config_dirs (); /* FIXME: if this fail display an error (?) */
+		make_dcc_dirs ();
 	}
 
-	putenv (hexchat_lang);
-#endif
+	/* we MUST do this after load_config () AND before fe_init (thus gtk_init) otherwise it will fail */
+	set_locale ();
 
 #ifdef SOCKS
 	SOCKSinit (argv[0]);
@@ -1245,6 +1109,15 @@ main (int argc, char *argv[])
 
 	fe_init ();
 
+#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 */
+
 	xchat_init ();
 
 	fe_main ();