diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c index a8bd32f9..60540245 100644 --- a/src/common/cfgfiles.c +++ b/src/common/cfgfiles.c @@ -1359,3 +1359,25 @@ hexchat_fopen_file (const char *file, const char *mode, int xof_flags) return fh; } + +/* + * Returns a #GFile* to a file in HexChat's config dir. + * Must be g_object_unref()'d when done. + * @filename must be in utf8 encoding. + */ +GFile * +hexchat_open_gfile (const char *filename) +{ + GFile *file; + gchar *full_path, *full_path_fs; + + full_path = g_build_filename (get_xdir(), filename, NULL); + full_path_fs = g_filename_from_utf8 (full_path, -1, NULL, NULL, NULL); + + file = g_file_new_for_path (full_path_fs); + + g_free (full_path); + g_free (full_path_fs); + + return file; +} diff --git a/src/common/cfgfiles.h b/src/common/cfgfiles.h index 8b996ca0..17f2edb9 100644 --- a/src/common/cfgfiles.h +++ b/src/common/cfgfiles.h @@ -50,6 +50,7 @@ void list_addentry (GSList ** list, char *cmd, char *name); int cmd_set (session *sess, char *tbuf, char *word[], char *word_eol[]); int hexchat_open_file (char *file, int flags, int mode, int xof_flags); FILE *hexchat_fopen_file (const char *file, const char *mode, int xof_flags); +GFile *hexchat_open_gfile (const char *filename); #define XOF_DOMODE 1 #define XOF_FULLPATH 2 diff --git a/src/common/servlist.c b/src/common/servlist.c index 7de77596..21db91de 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -1179,9 +1179,10 @@ servlist_load_defaults (void) static int servlist_load (void) { - FILE *fp; - char buf[2048]; - int len; + GFile *file; + GInputStream *stream; + GDataInputStream *istream; + gchar *buf; ircnet *net = NULL; /* simple migration we will keep for a short while */ @@ -1196,15 +1197,19 @@ servlist_load (void) g_free (oldfile); g_free (newfile); - fp = hexchat_fopen_file ("servlist.conf", "r", 0); - if (!fp) + + file = hexchat_open_gfile ("servlist.conf"); + + stream = G_INPUT_STREAM(g_file_read (file, NULL, NULL)); + if (!stream) return FALSE; - while (fgets (buf, sizeof (buf) - 2, fp)) + istream = g_data_input_stream_new (stream); + g_data_input_stream_set_newline_type (istream, G_DATA_STREAM_NEWLINE_TYPE_ANY); + g_object_unref (stream); + + while ((buf = g_data_input_stream_read_line_utf8 (istream, NULL, NULL, NULL))) { - len = strlen (buf); - buf[len] = 0; - buf[len-1] = 0; /* remove the trailing \n */ if (net) { switch (buf[0]) @@ -1277,8 +1282,12 @@ servlist_load (void) } if (buf[0] == 'N') net = servlist_net_add (buf + 2, /* comment */ NULL, FALSE); + + g_free (buf); } - fclose (fp); + + g_object_unref (file); + g_object_unref (istream); return TRUE; } @@ -1323,11 +1332,27 @@ servlist_check_encoding (char *charset) return FALSE; } +G_GNUC_PRINTF (2, 3) +static gsize +servlist_writeline (GOutputStream *ostream, const char *fmt, ...) +{ + char buf[512]; + va_list args; + gsize len; + + va_start (args, fmt); + len = g_vsnprintf (buf, sizeof (buf), fmt, args); + va_end (args); + + return g_output_stream_write (ostream, buf, len, NULL, NULL); +} + int servlist_save (void) { - FILE *fp; - char *buf; + GFile *file; + GOutputStream *ostream; + gchar *buf; ircnet *net; ircserver *serv; commandentry *cmd; @@ -1336,53 +1361,38 @@ servlist_save (void) GSList *netlist; GSList *cmdlist; GSList *favlist; -#ifndef WIN32 - int first = FALSE; - buf = g_build_filename (get_xdir (), "servlist.conf", NULL); - if (g_access (buf, F_OK) != 0) - first = TRUE; -#endif + file = hexchat_open_gfile ("servlist.conf"); - fp = hexchat_fopen_file ("servlist.conf", "w", 0); - if (!fp) - { -#ifndef WIN32 - g_free (buf); -#endif + ostream = G_OUTPUT_STREAM(g_file_replace (file, NULL, TRUE, + G_FILE_CREATE_PRIVATE, NULL, NULL)); + if (!ostream) return FALSE; - } -#ifndef WIN32 - if (first) - g_chmod (buf, 0600); - - g_free (buf); -#endif - fprintf (fp, "v=" PACKAGE_VERSION "\n\n"); + servlist_writeline (ostream, "v=%s\n\n", PACKAGE_VERSION); list = network_list; while (list) { net = list->data; - fprintf (fp, "N=%s\n", net->name); + servlist_writeline (ostream, "N=%s\n", net->name); if (net->nick) - fprintf (fp, "I=%s\n", net->nick); + servlist_writeline (ostream, "I=%s\n", net->nick); if (net->nick2) - fprintf (fp, "i=%s\n", net->nick2); + servlist_writeline (ostream, "i=%s\n", net->nick2); if (net->user) - fprintf (fp, "U=%s\n", net->user); + servlist_writeline (ostream, "U=%s\n", net->user); if (net->real) - fprintf (fp, "R=%s\n", net->real); + servlist_writeline (ostream, "R=%s\n", net->real); if (net->pass) - fprintf (fp, "P=%s\n", net->pass); + servlist_writeline (ostream, "P=%s\n", net->pass); if (net->logintype) - fprintf (fp, "L=%d\n", net->logintype); + servlist_writeline (ostream, "L=%d\n", net->logintype); if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") && g_ascii_strcasecmp (net->encoding, "System default")) { - fprintf (fp, "E=%s\n", net->encoding); + servlist_writeline (ostream, "E=%s\n", net->encoding); if (!servlist_check_encoding (net->encoding)) { buf = g_strdup_printf (_("Warning: \"%s\" character set is unknown. No conversion will be applied for network %s."), @@ -1392,13 +1402,13 @@ servlist_save (void) } } - fprintf (fp, "F=%d\nD=%d\n", net->flags, net->selected); + servlist_writeline (ostream, "F=%d\nD=%d\n", net->flags, net->selected); netlist = net->servlist; while (netlist) { serv = netlist->data; - fprintf (fp, "S=%s\n", serv->hostname); + servlist_writeline (ostream, "S=%s\n", serv->hostname); netlist = netlist->next; } @@ -1406,7 +1416,7 @@ servlist_save (void) while (cmdlist) { cmd = cmdlist->data; - fprintf (fp, "C=%s\n", cmd->command); + servlist_writeline (ostream, "C=%s\n", cmd->command); cmdlist = cmdlist->next; } @@ -1417,26 +1427,24 @@ servlist_save (void) if (favchan->key) { - fprintf (fp, "J=%s,%s\n", favchan->name, favchan->key); + servlist_writeline (ostream, "J=%s,%s\n", favchan->name, favchan->key); } else { - fprintf (fp, "J=%s\n", favchan->name); + servlist_writeline (ostream, "J=%s\n", favchan->name); } favlist = favlist->next; } - if (fprintf (fp, "\n") < 1) - { - fclose (fp); + if (!servlist_writeline (ostream, "\n")) return FALSE; - } list = list->next; } - fclose (fp); + g_object_unref (file); + g_object_unref (ostream); return TRUE; }