--- Begin Message ---
Package: release.debian.org
User: release.debian.org@packages.debian.org
Usertags: unblock
Severity: normal
Hello,
Please unblock xchat 2.8.8-7. It fixes "grave" bug 147832 about loss of data
when the disk is full. Debdiff attached. It's basically ten times the same
approach like I did for bug 463072.
Regards,
Bart Martens
diff -Nru xchat-2.8.8/debian/changelog xchat-2.8.8/debian/changelog
--- xchat-2.8.8/debian/changelog 2012-06-13 18:07:56.000000000 +0000
+++ xchat-2.8.8/debian/changelog 2012-09-30 15:19:00.000000000 +0000
@@ -1,3 +1,20 @@
+xchat (2.8.8-7) unstable; urgency=low
+
+ * The "Just Married" release.
+ * debian/patches/56_save_servlist.patch: Added. Closes: #147832.
+ Added more similar patches :
+ debian/patches/57_save_url.patch
+ debian/patches/58_save_notify.patch
+ debian/patches/59_save_colors.patch
+ debian/patches/60_save_chanlist.patch
+ debian/patches/61_save_editlist.patch
+ debian/patches/62_save_chanopt.patch
+ debian/patches/63_save_keybindings.patch
+ debian/patches/64_save_pevents.patch
+ debian/patches/65_save_sound.patch
+
+ -- Bart Martens <bartm@debian.org> Sun, 30 Sep 2012 08:57:19 +0000
+
xchat (2.8.8-6) unstable; urgency=high
* The "Euro 2012" release.
diff -Nru xchat-2.8.8/debian/patches/56_save_servlist.patch xchat-2.8.8/debian/patches/56_save_servlist.patch
--- xchat-2.8.8/debian/patches/56_save_servlist.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/56_save_servlist.patch 2012-09-30 15:21:39.000000000 +0000
@@ -0,0 +1,129 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+Closes: #147832.
+
+Index: xchat-2.8.8/src/common/servlist.c
+===================================================================
+--- xchat-2.8.8.orig/src/common/servlist.c 2012-09-30 12:23:53.000000000 +0000
++++ xchat-2.8.8/src/common/servlist.c 2012-09-30 12:23:55.000000000 +0000
+@@ -1072,6 +1072,7 @@
+ servlist_save (void)
+ {
+ FILE *fp;
++ int nb;
+ char buf[256];
+ ircnet *net;
+ ircserver *serv;
+@@ -1080,12 +1081,12 @@
+ #ifndef WIN32
+ int first = FALSE;
+
+- snprintf (buf, sizeof (buf), "%s/servlist_.conf", get_xdir_fs ());
++ snprintf (buf, sizeof (buf), "%s/servlist_.conf.bug147832", get_xdir_fs ());
+ if (access (buf, F_OK) != 0)
+ first = TRUE;
+ #endif
+
+- fp = xchat_fopen_file ("servlist_.conf", "w", 0);
++ fp = xchat_fopen_file ("servlist_.conf.bug147832", "w", 0);
+ if (!fp)
+ return FALSE;
+
+@@ -1093,32 +1094,32 @@
+ if (first)
+ chmod (buf, 0600);
+ #endif
+- fprintf (fp, "v="PACKAGE_VERSION"\n\n");
++ nb = fprintf (fp, "v="PACKAGE_VERSION"\n\n");
+
+ list = network_list;
+ while (list)
+ {
+ net = list->data;
+
+- fprintf (fp, "N=%s\n", net->name);
++ if( nb > 0 ) nb = fprintf (fp, "N=%s\n", net->name);
+ if (net->nick)
+- fprintf (fp, "I=%s\n", net->nick);
++ if( nb > 0 ) nb = fprintf (fp, "I=%s\n", net->nick);
+ if (net->nick2)
+- fprintf (fp, "i=%s\n", net->nick2);
++ if( nb > 0 ) nb = fprintf (fp, "i=%s\n", net->nick2);
+ if (net->user)
+- fprintf (fp, "U=%s\n", net->user);
++ if( nb > 0 ) nb = fprintf (fp, "U=%s\n", net->user);
+ if (net->real)
+- fprintf (fp, "R=%s\n", net->real);
++ if( nb > 0 ) nb = fprintf (fp, "R=%s\n", net->real);
+ if (net->pass)
+- fprintf (fp, "P=%s\n", net->pass);
++ if( nb > 0 ) nb = fprintf (fp, "P=%s\n", net->pass);
+ if (net->autojoin)
+- fprintf (fp, "J=%s\n", net->autojoin);
++ if( nb > 0 ) nb = fprintf (fp, "J=%s\n", net->autojoin);
+ if (net->nickserv)
+- fprintf (fp, "B=%s\n", net->nickserv);
++ if( nb > 0 ) nb = fprintf (fp, "B=%s\n", net->nickserv);
+ if (net->encoding && strcasecmp (net->encoding, "System") &&
+ strcasecmp (net->encoding, "System default"))
+ {
+- fprintf (fp, "E=%s\n", net->encoding);
++ if( nb > 0 ) nb = fprintf (fp, "E=%s\n", net->encoding);
+ if (!servlist_check_encoding (net->encoding))
+ {
+ snprintf (buf, sizeof (buf), _("Warning: \"%s\" character set is unknown. No conversion will be applied for network %s."),
+@@ -1128,28 +1129,44 @@
+ }
+
+ if (net->command)
+- token_foreach (net->command, '\n', servlist_write_ccmd, fp);
++ if( nb > 0 )
++ if( token_foreach (net->command, '\n', servlist_write_ccmd, fp) != TRUE )
++ nb = -1;
+
+- fprintf (fp, "F=%d\nD=%d\n", net->flags, net->selected);
++ if( nb > 0 ) nb = fprintf (fp, "F=%d\nD=%d\n", net->flags, net->selected);
+
+ hlist = net->servlist;
+ while (hlist)
+ {
+ serv = hlist->data;
+- fprintf (fp, "S=%s\n", serv->hostname);
++ if( nb > 0 ) nb = fprintf (fp, "S=%s\n", serv->hostname);
+ hlist = hlist->next;
+ }
+
+- if (fprintf (fp, "\n") < 1)
+- {
+- fclose (fp);
+- return FALSE;
+- }
++ if( nb > 0 ) nb = fprintf (fp, "\n");
+
+ list = list->next;
+ }
+
+- fclose (fp);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "servlist_save: fprintf() failed\n" );
++ fclose( fp );
++ return FALSE;
++ }
++
++ if( fclose (fp) != 0 )
++ {
++ perror( "servlist_save: fclose() failed" );
++ return FALSE;
++ }
++
++ if( xchat_rename_file( "servlist_.conf.bug147832", "servlist_.conf", 0 ) != 0 )
++ {
++ perror( "servlist_save: xchat_rename_file() failed" );
++ return FALSE;
++ }
++
+ return TRUE;
+ }
+
diff -Nru xchat-2.8.8/debian/patches/57_save_url.patch xchat-2.8.8/debian/patches/57_save_url.patch
--- xchat-2.8.8/debian/patches/57_save_url.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/57_save_url.patch 2012-09-30 15:21:52.000000000 +0000
@@ -0,0 +1,138 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+diff -ruN -x '*.png' -x '*.jpg' -x '*.ogg' -x '*_image_archive' -x '*.swp' ../orig/xchat-2.8.8/src/common/tree.c ./src/common/tree.c
+--- ../orig/xchat-2.8.8/src/common/tree.c 2009-08-16 09:40:16.000000000 +0000
++++ ./src/common/tree.c 2012-09-30 12:27:09.000000000 +0000
+@@ -176,19 +176,27 @@
+ return 1;
+ }
+
+-void
+-tree_foreach (tree *t, tree_traverse_func *func, void *data)
++int
++tree_foreach_int (tree *t, tree_traverse_func *func, void *data)
+ {
+ int j;
+
+ if (!t || !t->array)
+- return;
++ return 1;
+
+ for (j = 0; j < t->elements; j++)
+ {
+ if (!func (t->array[j], data))
+- break;
++ return 0;
+ }
++
++ return 1;
++}
++
++void
++tree_foreach (tree *t, tree_traverse_func *func, void *data)
++{
++ tree_foreach_int( t, func, data );
+ }
+
+ int
+diff -ruN -x '*.png' -x '*.jpg' -x '*.ogg' -x '*_image_archive' -x '*.swp' ../orig/xchat-2.8.8/src/common/tree.h ./src/common/tree.h
+--- ../orig/xchat-2.8.8/src/common/tree.h 2009-08-16 09:40:16.000000000 +0000
++++ ./src/common/tree.h 2012-09-30 12:27:09.000000000 +0000
+@@ -11,6 +11,7 @@
+ void *tree_find (tree *t, void *key, tree_cmp_func *cmp, void *data, int *pos);
+ int tree_remove (tree *t, void *key, int *pos);
+ void tree_foreach (tree *t, tree_traverse_func *func, void *data);
++int tree_foreach_int (tree *t, tree_traverse_func *func, void *data);
+ int tree_insert (tree *t, void *key);
+
+ #endif
+diff -ruN -x '*.png' -x '*.jpg' -x '*.ogg' -x '*_image_archive' -x '*.swp' ../orig/xchat-2.8.8/src/common/url.c ./src/common/url.c
+--- ../orig/xchat-2.8.8/src/common/url.c 2009-08-16 09:40:16.000000000 +0000
++++ ./src/common/url.c 2012-09-30 12:27:09.000000000 +0000
+@@ -50,11 +50,12 @@
+ static int
+ url_save_cb (char *url, FILE *fd)
+ {
+- fprintf (fd, "%s\n", url);
++ if( fprintf (fd, "%s\n", url) <= 0 )
++ return FALSE;
+ return TRUE;
+ }
+
+-void
++int
+ url_save (const char *fname, const char *mode, gboolean fullpath)
+ {
+ FILE *fd;
+@@ -64,10 +65,18 @@
+ else
+ fd = xchat_fopen_file (fname, mode, 0);
+ if (fd == NULL)
+- return;
++ return FALSE;
++
++ if( tree_foreach_int (url_tree, (tree_traverse_func *)url_save_cb, fd) == 0 )
++ {
++ fclose (fd);
++ return FALSE;
++ }
+
+- tree_foreach (url_tree, (tree_traverse_func *)url_save_cb, fd);
+- fclose (fd);
++ if( fclose (fd) )
++ return FALSE;
++
++ return TRUE;
+ }
+
+ void
+diff -ruN -x '*.png' -x '*.jpg' -x '*.ogg' -x '*_image_archive' -x '*.swp' ../orig/xchat-2.8.8/src/common/url.h ./src/common/url.h
+--- ../orig/xchat-2.8.8/src/common/url.h 2009-08-16 09:40:16.000000000 +0000
++++ ./src/common/url.h 2012-09-30 12:27:09.000000000 +0000
+@@ -11,7 +11,7 @@
+ #define WORD_DIALOG -1
+
+ void url_clear (void);
+-void url_save (const char *fname, const char *mode, gboolean fullpath);
++int url_save (const char *fname, const char *mode, gboolean fullpath);
+ void url_autosave (void);
+ int url_check_word (char *word, int len);
+ void url_check_line (char *buf, int len);
+--- ../orig/xchat-2.8.8/./src/fe-gtk/urlgrab.c 2010-05-16 03:16:37.000000000 +0000
++++ ./src/fe-gtk/urlgrab.c 2012-09-30 12:36:04.000000000 +0000
+@@ -136,8 +136,31 @@
+ static void
+ url_save_callback (void *arg1, char *file)
+ {
+- if (file)
+- url_save (file, "w", TRUE);
++ if( ! file )
++ return;
++
++ char *file_tmp = malloc( strlen( file ) + strlen( ".bug147832" ) + 1 );
++ if( ! file_tmp )
++ return;
++
++ strcpy( file_tmp, file );
++ strcat( file_tmp, ".bug147832" );
++
++ if( url_save( file_tmp, "w", TRUE ) != TRUE )
++ {
++ fprintf( stderr, "url_save_callback: url_save failed (%s)\n", file_tmp );
++ free( file_tmp );
++ return;
++ }
++
++ if( xchat_rename_file( file_tmp, file, XOF_FULLPATH ) != 0 )
++ {
++ perror( "url_save_callback: xchat_rename_file() failed" );
++ free( file_tmp );
++ return;
++ }
++
++ free( file_tmp );
+ }
+
+ static void
diff -Nru xchat-2.8.8/debian/patches/58_save_notify.patch xchat-2.8.8/debian/patches/58_save_notify.patch
--- xchat-2.8.8/debian/patches/58_save_notify.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/58_save_notify.patch 2012-09-30 15:22:10.000000000 +0000
@@ -0,0 +1,61 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+--- ../orig/xchat-2.8.8/./src/common/notify.c 2009-08-16 09:40:16.000000000 +0000
++++ ./src/common/notify.c 2012-09-30 12:53:27.000000000 +0000
+@@ -121,25 +121,47 @@
+ notify_save (void)
+ {
+ int fh;
++ ssize_t nb;
+ struct notify *notify;
+ GSList *list = notify_list;
+
+- fh = xchat_open_file ("notify.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
+- if (fh != -1)
++ fh = xchat_open_file ("notify.conf.bug147832", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
++ if( fh == -1 )
+ {
++ perror( "notify_save: xchat_open_file failed" );
++ return;
++ }
++ else
++ {
++ nb = 1;
+ while (list)
+ {
+ notify = (struct notify *) list->data;
+- write (fh, notify->name, strlen (notify->name));
++ if( nb > 0 ) nb = write (fh, notify->name, strlen (notify->name));
+ if (notify->networks)
+ {
+- write (fh, " ", 1);
+- write (fh, notify->networks, strlen (notify->networks));
++ if( nb > 0 ) nb = write (fh, " ", 1);
++ if( nb > 0 ) nb = write (fh, notify->networks, strlen (notify->networks));
+ }
+- write (fh, "\n", 1);
++ if( nb > 0 ) nb = write (fh, "\n", 1);
+ list = list->next;
+ }
+- close (fh);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "notify_save: fprintf() failed\n" );
++ close( fh );
++ return;
++ }
++ if( close (fh) != 0 )
++ {
++ perror( "notify_save: close failed" );
++ return;
++ }
++ if( xchat_rename_file( "notify.conf.bug147832", "notify.conf", XOF_DOMODE ) != 0 )
++ {
++ perror( "notify_save: xchat_rename_file() failed" );
++ return;
++ }
+ }
+ }
+
diff -Nru xchat-2.8.8/debian/patches/59_save_colors.patch xchat-2.8.8/debian/patches/59_save_colors.patch
--- xchat-2.8.8/debian/patches/59_save_colors.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/59_save_colors.patch 2012-09-30 16:20:43.000000000 +0000
@@ -0,0 +1,56 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+--- ../orig/xchat-2.8.8/./src/fe-gtk/palette.c 2010-05-16 03:16:10.000000000 +0000
++++ ./src/fe-gtk/palette.c 2012-09-30 12:58:02.000000000 +0000
+@@ -202,25 +202,45 @@
+ palette_save (void)
+ {
+ int i, j, fh;
++ ssize_t nb;
+ char prefname[256];
+
+- fh = xchat_open_file ("colors.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
++ fh = xchat_open_file ("colors.conf.bug147832", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
+ if (fh != -1)
+ {
++ nb = 1;
++
+ /* mIRC colors 0-31 are here */
+ for (i = 0; i < 32; i++)
+ {
+ snprintf (prefname, sizeof prefname, "color_%d", i);
+- cfg_put_color (fh, colors[i].red, colors[i].green, colors[i].blue, prefname);
++ if( nb > 0 ) nb = cfg_put_color (fh, colors[i].red, colors[i].green, colors[i].blue, prefname);
+ }
+
+ /* our special colors are mapped at 256+ */
+ for (i = 256, j = 32; j < MAX_COL+1; i++, j++)
+ {
+ snprintf (prefname, sizeof prefname, "color_%d", i);
+- cfg_put_color (fh, colors[j].red, colors[j].green, colors[j].blue, prefname);
++ if( nb > 0 ) nb = cfg_put_color (fh, colors[j].red, colors[j].green, colors[j].blue, prefname);
+ }
+
+- close (fh);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "palette_save: cfg_put_color failed\n" );
++ close( fh );
++ return;
++ }
++
++ if( close (fh) != 0 )
++ {
++ perror( "palette_save: close() failed\n" );
++ return;
++ }
++
++ if( xchat_rename_file( "colors.conf.bug147832", "colors.conf", XOF_DOMODE ) != 0 )
++ {
++ perror( "palette_save: xchat_rename_file() failed" );
++ return;
++ }
+ }
+ }
diff -Nru xchat-2.8.8/debian/patches/60_save_chanlist.patch xchat-2.8.8/debian/patches/60_save_chanlist.patch
--- xchat-2.8.8/debian/patches/60_save_chanlist.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/60_save_chanlist.patch 2012-09-30 15:22:21.000000000 +0000
@@ -0,0 +1,79 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+--- ../orig/xchat-2.8.8/./src/fe-gtk/chanlist.c 2009-08-16 09:40:18.000000000 +0000
++++ ./src/fe-gtk/chanlist.c 2012-09-30 13:09:03.000000000 +0000
+@@ -480,6 +480,7 @@
+ {
+ time_t t = time (0);
+ int fh, users;
++ ssize_t nb;
+ char *chan, *topic;
+ char buf[1024];
+ GtkTreeModel *model = GET_MODEL (serv);
+@@ -488,14 +489,25 @@
+ if (!file)
+ return;
+
+- fh = xchat_open_file (file, O_TRUNC | O_WRONLY | O_CREAT, 0600,
++ char *file_tmp = malloc( strlen( file ) + strlen( ".bug147832" ) + 1 );
++ if( ! file_tmp )
++ return;
++
++ strcpy( file_tmp, file );
++ strcat( file_tmp, ".bug147832" );
++
++ fh = xchat_open_file (file_tmp, O_TRUNC | O_WRONLY | O_CREAT, 0600,
+ XOF_DOMODE | XOF_FULLPATH);
+ if (fh == -1)
++ {
++ perror( "chanlist_filereq_done: xchat_open_file failed" );
++ free( file_tmp );
+ return;
++ }
+
+ snprintf (buf, sizeof buf, "XChat Channel List: %s - %s\n",
+ serv->servername, ctime (&t));
+- write (fh, buf, strlen (buf));
++ nb = write (fh, buf, strlen (buf));
+
+ if (gtk_tree_model_get_iter_first (model, &iter))
+ {
+@@ -508,12 +520,34 @@
+ snprintf (buf, sizeof buf, "%-16s %-5d%s\n", chan, users, topic);
+ g_free (chan);
+ g_free (topic);
+- write (fh, buf, strlen (buf));
++ if( nb > 0 ) nb = write (fh, buf, strlen (buf));
+ }
+ while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+- close (fh);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "chanlist_filereq_done: write() failed\n" );
++ close( fh );
++ free( file_tmp );
++ return;
++ }
++
++ if( close (fh) != 0 )
++ {
++ perror( "chanlist_filereq_done: close() failed" );
++ free( file_tmp );
++ return;
++ }
++
++ if( xchat_rename_file( file_tmp, file, XOF_DOMODE | XOF_FULLPATH ) != 0 )
++ {
++ perror( "chanlist_filereq_done: xchat_rename_file() failed" );
++ free( file_tmp );
++ return;
++ }
++
++ free( file_tmp );
+ }
+
+ static void
diff -Nru xchat-2.8.8/debian/patches/61_save_editlist.patch xchat-2.8.8/debian/patches/61_save_editlist.patch
--- xchat-2.8.8/debian/patches/61_save_editlist.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/61_save_editlist.patch 2012-09-30 15:22:25.000000000 +0000
@@ -0,0 +1,58 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+--- ../orig/xchat-2.8.8/./src/fe-gtk/editlist.c 2009-08-16 09:40:18.000000000 +0000
++++ ./src/fe-gtk/editlist.c 2012-09-30 15:02:05.000000000 +0000
+@@ -161,22 +161,48 @@
+ editlist_gui_save (GtkWidget * igad)
+ {
+ int fh, i = 0;
++ ssize_t nb;
+ char buf[512];
+ char *a, *b;
+
+- fh = xchat_open_file (editlist_file, O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
++ char *file_tmp = malloc( strlen( editlist_file ) + strlen( ".bug147832" ) + 1 );
++ if( ! file_tmp )
++ return;
++
++ fh = xchat_open_file (file_tmp, O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
+ if (fh != -1)
+ {
++ nb = 1;
+ while (1)
+ {
+ if (!gtk_clist_get_text (GTK_CLIST (editlist_gui_list), i, 0, &a))
+ break;
+ gtk_clist_get_text (GTK_CLIST (editlist_gui_list), i, 1, &b);
+ snprintf (buf, sizeof (buf), "NAME %s\nCMD %s\n\n", a, b);
+- write (fh, buf, strlen (buf));
++ if( nb > 0 ) nb = write (fh, buf, strlen (buf));
+ i++;
+ }
+- close (fh);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "editlist_gui_save: write() failed\n" );
++ close( fh );
++ free( file_tmp );
++ return;
++ }
++ if( close (fh) != 0 )
++ {
++ perror( "editlist_gui_save: close() failed" );
++ free( file_tmp );
++ return;
++ }
++ if( xchat_rename_file( file_tmp, editlist_file, XOF_DOMODE ) != 0 )
++ {
++ perror( "editlist_gui_save: xchat_rename_file() failed" );
++ free( file_tmp );
++ return;
++ }
++ free( file_tmp );
++
+ gtk_widget_destroy (editlist_gui_window);
+ if (editlist_list == replace_list)
+ {
diff -Nru xchat-2.8.8/debian/patches/62_save_chanopt.patch xchat-2.8.8/debian/patches/62_save_chanopt.patch
--- xchat-2.8.8/debian/patches/62_save_chanopt.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/62_save_chanopt.patch 2012-09-30 16:20:57.000000000 +0000
@@ -0,0 +1,119 @@
+--- ../orig/xchat-2.8.8/./src/common/chanopt.c 2009-08-16 09:40:16.000000000 +0000
++++ ./src/common/chanopt.c 2012-09-30 15:30:55.000000000 +0000
+@@ -345,7 +345,7 @@
+ }
+ }
+
+-static void
++static int
+ chanopt_save_one_channel (chanopt_in_memory *co, int fh)
+ {
+ int i;
+@@ -353,10 +353,12 @@
+ guint8 val;
+
+ snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network);
+- write (fh, buf, strlen (buf));
++ if( write (fh, buf, strlen (buf)) <= 0 )
++ return FALSE;
+
+ snprintf (buf, sizeof (buf), "%s = %s\n", "channel", co->channel);
+- write (fh, buf, strlen (buf));
++ if( write (fh, buf, strlen (buf)) <= 0 )
++ return FALSE;
+
+ i = 0;
+ while (i < sizeof (chanopt) / sizeof (channel_options))
+@@ -365,10 +367,13 @@
+ if (val != SET_DEFAULT)
+ {
+ snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val);
+- write (fh, buf, strlen (buf));
++ if( write (fh, buf, strlen (buf)) <= 0 )
++ return FALSE;
+ }
+ i++;
+ }
++
++ return TRUE;
+ }
+
+ void
+@@ -377,6 +382,7 @@
+ int i;
+ int num_saved;
+ int fh;
++ ssize_t nb;
+ GSList *list;
+ chanopt_in_memory *co;
+ guint8 val;
+@@ -386,12 +392,14 @@
+ return;
+ }
+
+- fh = xchat_open_file ("chanopt.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
++ fh = xchat_open_file ("chanopt.conf.bug147832", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
+ if (fh == -1)
+ {
+ return;
+ }
+
++ nb = 1;
++
+ for (num_saved = 0, list = chanopt_list; list; list = list->next)
+ {
+ co = list->data;
+@@ -404,9 +412,11 @@
+ if (val != SET_DEFAULT)
+ {
+ if (num_saved != 0)
+- write (fh, "\n", 1);
++ if( nb > 0 ) nb = write (fh, "\n", 1);
+
+- chanopt_save_one_channel (co, fh);
++ if( nb > 0 )
++ if( chanopt_save_one_channel (co, fh) != TRUE )
++ nb = -1;
+ num_saved++;
+ goto cont;
+ }
+@@ -414,13 +424,37 @@
+ }
+
+ cont:
++ ;
++ }
++
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "chanopt_save_all: write() failed\n" );
++ close( fh );
++ return;
++ }
++
++ if( close (fh) != 0 )
++ {
++ perror( "chanopt_save_all: close() failed" );
++ return;
++ }
++
++ if( xchat_rename_file( "chanopt.conf.bug147832", "chanopt.conf", XOF_DOMODE ) != 0 )
++ {
++ perror( "chanopt_save_all: xchat_rename_file() failed" );
++ return;
++ }
++
++ for (list = chanopt_list; list; list = list->next)
++ {
++ co = list->data;
++
+ g_free (co->network);
+ g_free (co->channel);
+ g_free (co);
+ }
+
+- close (fh);
+-
+ /* we're quiting, no need to free */
+
+ /*g_slist_free (chanopt_list);
diff -Nru xchat-2.8.8/debian/patches/63_save_keybindings.patch xchat-2.8.8/debian/patches/63_save_keybindings.patch
--- xchat-2.8.8/debian/patches/63_save_keybindings.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/63_save_keybindings.patch 2012-09-30 15:22:35.000000000 +0000
@@ -0,0 +1,136 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+--- ../orig/xchat-2.8.8/./src/fe-gtk/fkeys.c 2009-08-16 09:40:18.000000000 +0000
++++ ./src/fe-gtk/fkeys.c 2012-09-30 14:09:09.000000000 +0000
+@@ -837,22 +837,35 @@
+ static void
+ key_save_kbs (char *fn)
+ {
+- int fd, i;
++ int fd, i, rc;
++ ssize_t nb;
+ char buf[512];
++ char *file_tmp = NULL;
+ struct key_binding *kb;
+
+ if (!fn)
+- fd = xchat_open_file ("keybindings.conf", O_CREAT | O_TRUNC | O_WRONLY,
++ fd = xchat_open_file ("keybindings.conf.bug147832", O_CREAT | O_TRUNC | O_WRONLY,
+ 0x180, XOF_DOMODE);
+ else
+- fd = xchat_open_file (fn, O_CREAT | O_TRUNC | O_WRONLY,
++ {
++ file_tmp = malloc( strlen( fn ) + strlen( ".bug147832" ) + 1 );
++ if( ! file_tmp )
++ return;
++ strcpy( file_tmp, fn );
++ strcat( file_tmp, ".bug147832" );
++
++ fd = xchat_open_file (file_tmp, O_CREAT | O_TRUNC | O_WRONLY,
+ 0x180, XOF_DOMODE | XOF_FULLPATH);
++ }
++
+ if (fd < 0)
+ {
+ fe_message (_("Error opening keys config file\n"), FE_MSG_ERROR);
++ if( file_tmp )
++ free( file_tmp );
+ return;
+ }
+- write (fd, buf,
++ nb = write (fd, buf,
+ snprintf (buf, 510, "# XChat key bindings config file\n\n"));
+
+ kb = keys_root;
+@@ -869,41 +882,77 @@
+ if (kb->mod & STATE_CTRL)
+ {
+ i++;
+- write (fd, "C", 1);
++ if( nb > 0 ) nb = write (fd, "C", 1);
+ }
+ if (kb->mod & STATE_ALT)
+ {
+ i++;
+- write (fd, "A", 1);
++ if( nb > 0 ) nb = write (fd, "A", 1);
+ }
+ if (kb->mod & STATE_SHIFT)
+ {
+ i++;
+- write (fd, "S", 1);
++ if( nb > 0 ) nb = write (fd, "S", 1);
+ }
+ if (i == 0)
+- write (fd, "None\n", 5);
++ {
++ if( nb > 0 ) nb = write (fd, "None\n", 5);
++ }
+ else
+- write (fd, "\n", 1);
++ if( nb > 0 ) nb = write (fd, "\n", 1);
+
+- write (fd, buf, snprintf (buf, 510, "%s\n%s\n", kb->keyname,
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, 510, "%s\n%s\n", kb->keyname,
+ key_actions[kb->action].name));
+ if (kb->data1 && kb->data1[0])
+- write (fd, buf, snprintf (buf, 510, "D1:%s\n", kb->data1));
++ {
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, 510, "D1:%s\n", kb->data1));
++ }
+ else
+- write (fd, "D1!\n", 4);
++ if( nb > 0 ) nb = write (fd, "D1!\n", 4);
+
+ if (kb->data2 && kb->data2[0])
+- write (fd, buf, snprintf (buf, 510, "D2:%s\n", kb->data2));
++ {
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, 510, "D2:%s\n", kb->data2));
++ }
+ else
+- write (fd, "D2!\n", 4);
++ if( nb > 0 ) nb = write (fd, "D2!\n", 4);
+
+- write (fd, "\n", 1);
++ if( nb > 0 ) nb = write (fd, "\n", 1);
+
+ kb = kb->next;
+ }
+
+- close (fd);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "key_save_kbs: write() failed\n" );
++ close( fd );
++ if( file_tmp )
++ free( file_tmp );
++ return;
++ }
++
++ if( close (fd) != 0 )
++ {
++ if( file_tmp )
++ free( file_tmp );
++ return;
++ }
++
++ if( ! fn )
++ rc = xchat_rename_file( "keybindings.conf.bug147832", "keybindings.conf", XOF_DOMODE );
++ else
++ rc = xchat_rename_file( file_tmp, fn, XOF_DOMODE | XOF_FULLPATH );
++
++ if( rc != 0 )
++ {
++ perror( "key_save_kbs: xchat_rename_file() failed" );
++ if( file_tmp )
++ free( file_tmp );
++ return;
++ }
++
++ if( file_tmp )
++ free( file_tmp );
+ }
+
+ /* I just know this is going to be a nasty parse, if you think it's bugged
diff -Nru xchat-2.8.8/debian/patches/64_save_pevents.patch xchat-2.8.8/debian/patches/64_save_pevents.patch
--- xchat-2.8.8/debian/patches/64_save_pevents.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/64_save_pevents.patch 2012-09-30 15:22:39.000000000 +0000
@@ -0,0 +1,92 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+--- ../orig/xchat-2.8.8/./src/common/text.c 2012-09-30 07:50:12.000000000 +0000
++++ ./src/common/text.c 2012-09-30 14:20:50.000000000 +0000
+@@ -2089,15 +2089,26 @@
+ void
+ pevent_save (char *fn)
+ {
+- int fd, i;
++ int fd, i, rc;
++ ssize_t nb;
++ char *file_tmp = NULL;
+ char buf[1024];
+
+ if (!fn)
+- fd = xchat_open_file ("pevents.conf", O_CREAT | O_TRUNC | O_WRONLY,
++ fd = xchat_open_file ("pevents.conf.bug147832", O_CREAT | O_TRUNC | O_WRONLY,
+ 0x180, XOF_DOMODE);
+ else
+- fd = xchat_open_file (fn, O_CREAT | O_TRUNC | O_WRONLY, 0x180,
++ {
++ file_tmp = malloc( strlen( fn ) + strlen( ".bug147832" ) + 1 );
++ if( ! file_tmp )
++ return;
++ strcpy( file_tmp, fn );
++ strcat( file_tmp, ".bug147832" );
++
++ fd = xchat_open_file (file_tmp, O_CREAT | O_TRUNC | O_WRONLY, 0x180,
+ XOF_FULLPATH | XOF_DOMODE);
++ }
++
+ if (fd == -1)
+ {
+ /*
+@@ -2107,18 +2118,52 @@
+ */
+
+ perror ("Error opening config file\n");
++ if( ! file_tmp )
++ free( file_tmp );
+ return;
+ }
+
++ nb = 1;
+ for (i = 0; i < NUM_XP; i++)
+ {
+- write (fd, buf, snprintf (buf, sizeof (buf),
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, sizeof (buf),
+ "event_name=%s\n", te[i].name));
+- write (fd, buf, snprintf (buf, sizeof (buf),
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, sizeof (buf),
+ "event_text=%s\n\n", pntevts_text[i]));
+ }
+
+- close (fd);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "pevent_save: write() failed\n" );
++ close( fd );
++ if( file_tmp )
++ free( file_tmp );
++ return;
++ }
++
++ if( close (fd) != 0 )
++ {
++ perror( "pevent_save: close() failed" );
++ if( file_tmp )
++ free( file_tmp );
++ return;
++ }
++
++ if( ! fn )
++ rc = xchat_rename_file( "pevents.conf.bug147832", "pevents.conf", XOF_DOMODE );
++ else
++ rc = xchat_rename_file( file_tmp, fn, XOF_FULLPATH | XOF_DOMODE );
++
++ if( rc != 0 )
++ {
++ perror( "pevent_save: xchat_rename_file() failed" );
++ if( file_tmp )
++ free( file_tmp );
++ return;
++ }
++
++ if( file_tmp )
++ free( file_tmp );
+ }
+
+ /* =========================== */
diff -Nru xchat-2.8.8/debian/patches/65_save_sound.patch xchat-2.8.8/debian/patches/65_save_sound.patch
--- xchat-2.8.8/debian/patches/65_save_sound.patch 1970-01-01 00:00:00.000000000 +0000
+++ xchat-2.8.8/debian/patches/65_save_sound.patch 2012-09-30 16:21:13.000000000 +0000
@@ -0,0 +1,56 @@
+Write to temporary file and then rename.
+Same approach like I did for bug 463072.
+Fixes loss of data when disk is full.
+
+Index: xchat-2.8.8/src/common/text.c
+===================================================================
+--- xchat-2.8.8.orig/src/common/text.c 2012-09-30 14:26:18.000000000 +0000
++++ xchat-2.8.8/src/common/text.c 2012-09-30 14:26:18.000000000 +0000
+@@ -2332,23 +2332,43 @@
+ sound_save ()
+ {
+ int fd, i;
++ ssize_t nb;
+ char buf[512];
+
+- fd = xchat_open_file ("sound.conf", O_CREAT | O_TRUNC | O_WRONLY, 0x180,
++ fd = xchat_open_file ("sound.conf.bug147832", O_CREAT | O_TRUNC | O_WRONLY, 0x180,
+ XOF_DOMODE);
+ if (fd == -1)
+ return;
+
++ nb = 1;
++
+ for (i = 0; i < NUM_XP; i++)
+ {
+ if (sound_files[i] && sound_files[i][0])
+ {
+- write (fd, buf, snprintf (buf, sizeof (buf),
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, sizeof (buf),
+ "event=%s\n", te[i].name));
+- write (fd, buf, snprintf (buf, sizeof (buf),
++ if( nb > 0 ) nb = write (fd, buf, snprintf (buf, sizeof (buf),
+ "sound=%s\n\n", sound_files[i]));
+ }
+ }
+
+- close (fd);
++ if( nb <= 0 )
++ {
++ fprintf( stderr, "sound_save: write() failed\n" );
++ close( fd );
++ return;
++ }
++
++ if( close (fd) != 0 )
++ {
++ perror( "sound_save: close() failed" );
++ return;
++ }
++
++ if( xchat_rename_file( "sound.conf.bug147832", "sound.conf", XOF_DOMODE ) != 0 )
++ {
++ perror( "sound_save: xchat_rename_file() failed" );
++ return;
++ }
+ }
diff -Nru xchat-2.8.8/debian/patches/series xchat-2.8.8/debian/patches/series
--- xchat-2.8.8/debian/patches/series 2012-06-13 18:14:02.000000000 +0000
+++ xchat-2.8.8/debian/patches/series 2012-09-30 14:28:29.000000000 +0000
@@ -13,3 +13,13 @@
53_russian.patch
54_glib_single_include.patch
55_hurd_build.patch
+56_save_servlist.patch
+57_save_url.patch
+58_save_notify.patch
+59_save_colors.patch
+60_save_chanlist.patch
+61_save_editlist.patch
+62_save_chanopt.patch
+63_save_keybindings.patch
+64_save_pevents.patch
+65_save_sound.patch
--- End Message ---