Package: release.debian.org User: release.debian....@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 <ba...@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