[pan2: 25/268] master



commit 129f910299c9c9c5803cd7ff4739a31940a46528
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date:   Sat May 21 16:44:20 2011 +0200

    master

 Makefile.am                                        |   33 +-
 pan/data-impl/server.cc                            |   11 +-
 pan/data/Makefile.am                               |   10 +-
 pan/data/article.h                                 |    4 +-
 pan/data/decode-test-cache/apostrophe.msg          |   13 -
 pan/data/decode-test-cache/collision.msg           |   23 -
 pan/data/decode-test-cache/micro.msg               |   12 -
 pan/data/decode-test-cache/noisy_1_2.msg           |  668 -------------------
 pan/data/decode-test-cache/noisy_2_2.msg           |  124 ----
 pan/data/decode-test-cache/penguin_1_2.msg         |  332 ----------
 pan/data/decode-test-cache/penguin_2_2.msg         |   41 --
 .../decode-test-cache/two_mime_attachments.msg     |  671 --------------------
 pan/data/decode-test-cache/two_uu_attachments.msg  |   18 -
 pan/data/decode-test-cache/xuuencode.msg           |  447 -------------
 pan/data/decode-test-cache/yenc.msg                |  Bin 2795 -> 0 bytes
 pan/data/decode-test-cache/yenc_1_2.msg            |  103 ---
 pan/data/decode-test-cache/yenc_2_2.msg            |   78 ---
 pan/data/parts.cc                                  |    2 +-
 pan/general/file-util.cc                           |    2 +-
 pan/general/progress.cc                            |    4 +-
 pan/gui/actions.cc                                 |   94 ++--
 pan/gui/gui.cc                                     |   58 +-
 pan/gui/gui.h                                      |    6 +-
 pan/gui/header-pane.cc                             |   11 +-
 pan/gui/pan-ui.h                                   |    1 +
 pan/gui/pan.ui.h                                   |    2 +
 pan/gui/post-ui.cc                                 |  247 ++++++--
 pan/gui/post-ui.h                                  |   22 +-
 pan/gui/post.ui.h                                  |    4 +-
 pan/gui/server-ui.cc                               |   45 +-
 pan/gui/task-pane.cc                               |    6 +-
 pan/tasks/Makefile.am                              |    4 +
 pan/tasks/nntp.cc                                  |   17 +
 pan/tasks/nntp.h                                   |    6 +
 pan/tasks/queue.cc                                 |   62 ++-
 pan/tasks/queue.h                                  |   19 +-
 pan/tasks/task-article.cc                          |    4 +-
 pan/tasks/task-post.cc                             |    1 +
 pan/tasks/task.cc                                  |   28 +
 pan/tasks/task.h                                   |   20 +-
 uulib/uuencode.c                                   |  148 +++---
 41 files changed, 596 insertions(+), 2805 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 3db545f..cfe49f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,32 +1,3 @@
-SUBDIRS = po uulib pan
+SUBDIRS = general usenet-utils data tasks data-impl icons gui
 
- INTLTOOL_DESKTOP_RULE@
-
-DESKTOP_IN_FILES=pan.desktop.in
-DESKTOP_FILES=$(DESKTOP_IN_FILES:.desktop.in=.desktop)
-
-DISTCLEANFILES = \
- intltool-extract \
- intltool-merge \
- intltool-update \
- pan.desktop
-
-
-EXTRA_DIST = \
- README \
- README.windows \
- README.mingw \
- ChangeLog \
- Pan.ico \
- pan.spec \
- pan.png \
- $(DESKTOP_IN_FILES) \
- $(DESKTOP_FILES) \
- intltool-extract.in intltool-merge.in intltool-update.in \
- pan_git_rev
-
-Productivitydir = $(datadir)/applications
-Productivity_DATA = $(DESKTOP_FILES)
-
-icon_DATA = pan.png
-icondir = $(datadir)/pixmaps
+EXTRA_DIST = pan.cfg
diff --git a/pan/data-impl/server.cc b/pan/data-impl/server.cc
index b927fb9..7dfa952 100644
--- a/pan/data-impl/server.cc
+++ b/pan/data-impl/server.cc
@@ -110,7 +110,7 @@ DataImpl :: set_server_article_expiration_age  (const Quark  & server,
   save_server_properties (*_data_io);
 }
 
-  
+
 void
 DataImpl :: set_server_auth (const Quark       & server,
                              const StringView  & username,
@@ -171,7 +171,7 @@ DataImpl :: get_server_auth (const Quark   & server,
   }
   return found;
 }
-                                                                                             
+
 bool
 DataImpl :: get_server_addr (const Quark   & server,
                              std::string   & setme_host,
@@ -272,7 +272,7 @@ namespace
 
   void text (GMarkupParseContext *context    UNUSED,
              const gchar         *text,
-             gsize                text_len,  
+             gsize                text_len,
              gpointer             user_data,
              GError             **error      UNUSED)
   {
@@ -375,7 +375,10 @@ DataImpl :: save_server_properties (DataIO& data_io) const
          << indent(depth) << "<expire-articles-n-days-old>" << s->article_expiration_age << "</expire-articles-n-days-old>\n"
          << indent(depth) << "<connection-limit>" << s->max_connections << "</connection-limit>\n"
          << indent(depth) << "<newsrc>" << s->newsrc_filename << "</newsrc>\n"
-         << indent(depth) << "<rank>" << s->rank << "</rank>\n";
+         << indent(depth) << "<rank>" << s->rank << "</rank>\n"
+         //todo
+         << indent(depth) << "<xzver>" << s->rank << "</xzver>\n";
+
     *out << indent(--depth) << "</server>\n";
   }
   *out << indent(--depth) << "</server-properties>\n";
diff --git a/pan/data/Makefile.am b/pan/data/Makefile.am
index 6ff3ebe..e899618 100644
--- a/pan/data/Makefile.am
+++ b/pan/data/Makefile.am
@@ -9,7 +9,8 @@ libdata_a_SOURCES = \
  article-cache.cc \
  data.cc \
  parts.cc \
- xref.cc
+ xref.cc \
+ file-queue.cc
 
 noinst_HEADERS = \
  article.h \
@@ -18,13 +19,14 @@ noinst_HEADERS = \
  defgroup.h \
  parts.h \
  server-info.h \
- xref.h 
+ xref.h \
+ file-queue.h
 
 noinst_PROGRAMS = \
  article-test \
- xref-test 
+ xref-test
 
-#dnl decode-test 
+#dnl decode-test
 #dnl decode_test_SOURCES = decode-test.cc
 #dnl decode_test_LDADD = $(TEST_LDADD)
 
diff --git a/pan/data/article.h b/pan/data/article.h
index 0d905b9..a2e0f9b 100644
--- a/pan/data/article.h
+++ b/pan/data/article.h
@@ -31,7 +31,7 @@ namespace pan
 {
   /**
    * A Usenet article, either single-part or multipart.
-   * 
+   *
    * To lessen the memory footprint of large binaries groups,
    * Pan folds multipart posts into a single Article object.
    * Only minimal information for any one part is kept
@@ -50,6 +50,7 @@ namespace pan
       void set_parts (const PartBatch& b) { parts.set_parts(b); }
       bool add_part (Parts::number_t num, const StringView& mid, Parts::bytes_t bytes) { return parts.add_part(num,mid,bytes,message_id); }
       void set_part_count (Parts::number_t num) { parts.set_part_count(num); }
+
       Parts::number_t get_total_part_count () const { return parts.get_total_part_count(); }
       Parts::number_t get_found_part_count () const { return parts.get_found_part_count(); }
       bool get_part_info (Parts::number_t      num,
@@ -86,6 +87,7 @@ namespace pan
 
     public:
       Article (): time_posted(0), lines(0), score(0), is_binary(false)  {}
+      Article (const bool bin): time_posted(0), lines(0), score(0), is_binary(bin)  {}
       void clear ();
 
     private:
diff --git a/pan/data/parts.cc b/pan/data/parts.cc
index 11cfe71..8b3181e 100644
--- a/pan/data/parts.cc
+++ b/pan/data/parts.cc
@@ -87,7 +87,7 @@ namespace
     for (; b!=bmax; ++b)
       if (*k++ != *m++)
         break;
-    
+
     const int emax = std::min (shorter-b, (int)UCHAR_MAX);
     k = &key.back();
     m = &mid.back();
diff --git a/pan/general/file-util.cc b/pan/general/file-util.cc
index 4945d83..55d3dd0 100644
--- a/pan/general/file-util.cc
+++ b/pan/general/file-util.cc
@@ -63,7 +63,7 @@ file :: get_pan_home ()
       g_free (pch);
     }
   }
-                                                                                                                                
+
   file :: ensure_dir_exists (pan_home);
   return pan_home;
 }
diff --git a/pan/general/progress.cc b/pan/general/progress.cc
index a01a9e5..b292ded 100644
--- a/pan/general/progress.cc
+++ b/pan/general/progress.cc
@@ -31,8 +31,8 @@ using namespace pan;
 
 void
 Progress :: fire_percentage (int p) {
-  for (listeners_cit it(_listeners.begin()), end(_listeners.end()); it!=end; )
-    (*it++)->on_progress_step (*this, p);
+//  for (listeners_cit it(_listeners.begin()), end(_listeners.end()); it!=end; )
+//    (*it++)->on_progress_step (*this, p);
 }
 void
 Progress :: fire_pulse () {
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index ef6eda2..af3ad55 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -46,23 +46,23 @@ namespace
   {
     { icon_article_read, "ICON_ARTICLE_READ" },
     { icon_article_unread, "ICON_ARTICLE_UNREAD" },
-    { icon_compose_followup, "ICON_COMPOSE_FOLLOWUP" }, 
-    { icon_compose_post, "ICON_COMPOSE_POST" }, 
-    { icon_disk, "ICON_DISK" }, 
-    { icon_filter_only_attachments, "ICON_ONLY_ATTACHMENTS" }, 
-    { icon_filter_only_cached, "ICON_ONLY_CACHED" }, 
-    { icon_filter_only_me, "ICON_ONLY_ME" }, 
-    { icon_filter_only_unread, "ICON_ONLY_UNREAD" }, 
-    { icon_filter_only_watched, "ICON_ONLY_WATCHED" }, 
-    { icon_get_dialog, "ICON_GET_DIALOG" }, 
-    { icon_get_selected, "ICON_GET_SELECTED" }, 
-    { icon_get_subscribed, "ICON_GET_SUBSCRIBED" }, 
-    { icon_read_group, "ICON_READ_GROUP" }, 
-    { icon_read_more, "ICON_READ_MORE" }, 
-    { icon_read_less, "ICON_READ_LESS" }, 
-    { icon_read_unread_article, "ICON_READ_UNREAD_ARTICLE" }, 
-    { icon_read_unread_thread, "ICON_READ_UNREAD_THREAD" }, 
-    { icon_score, "ICON_SCORE" }, 
+    { icon_compose_followup, "ICON_COMPOSE_FOLLOWUP" },
+    { icon_compose_post, "ICON_COMPOSE_POST" },
+    { icon_disk, "ICON_DISK" },
+    { icon_filter_only_attachments, "ICON_ONLY_ATTACHMENTS" },
+    { icon_filter_only_cached, "ICON_ONLY_CACHED" },
+    { icon_filter_only_me, "ICON_ONLY_ME" },
+    { icon_filter_only_unread, "ICON_ONLY_UNREAD" },
+    { icon_filter_only_watched, "ICON_ONLY_WATCHED" },
+    { icon_get_dialog, "ICON_GET_DIALOG" },
+    { icon_get_selected, "ICON_GET_SELECTED" },
+    { icon_get_subscribed, "ICON_GET_SUBSCRIBED" },
+    { icon_read_group, "ICON_READ_GROUP" },
+    { icon_read_more, "ICON_READ_MORE" },
+    { icon_read_less, "ICON_READ_LESS" },
+    { icon_read_unread_article, "ICON_READ_UNREAD_ARTICLE" },
+    { icon_read_unread_thread, "ICON_READ_UNREAD_THREAD" },
+    { icon_score, "ICON_SCORE" },
     { icon_search_pulldown, "ICON_SEARCH_PULLDOWN" }
   };
 
@@ -435,22 +435,22 @@ namespace
       NULL,
       G_CALLBACK(do_clear_header_pane) },
     { "clear-body-pane", NULL,
-      N_("Clear _Body Pane"), NULL, 
+      N_("Clear _Body Pane"), NULL,
       NULL,
       G_CALLBACK(do_clear_body_pane) },
 
     { "download-selected-article", "ICON_DISK",
-      N_("Cache Article"), NULL, 
+      N_("Cache Article"), NULL,
       NULL,
       G_CALLBACK(do_download_selected_article) },
 
     { "read-selected-article", "ICON_READ_MORE",
-      N_("Read Article"), NULL, 
+      N_("Read Article"), NULL,
       NULL,
       G_CALLBACK(do_read_selected_article) },
 
     { "show-selected-article-info", NULL,
-      N_("Show Article Information"), NULL, 
+      N_("Show Article Information"), NULL,
       NULL,
       G_CALLBACK(do_show_selected_article_info) },
 
@@ -459,18 +459,24 @@ namespace
       N_("Read More"),
       G_CALLBACK(do_read_more) },
 
+    // todo icon, move!
+//    { "binpost", "ICON_READ_MORE",
+//      N_("Post binary files"), "space",
+//      N_("Post binary files"),
+//      G_CALLBACK(do_binpost) },
+
     { "read-less", "ICON_READ_LESS",
       N_("Read _Back"), "BackSpace",
       N_("Read Back"),
       G_CALLBACK(do_read_less) },
 
     { "read-next-unread-group", "ICON_READ_UNREAD_GROUP",
-      N_("Next _Unread Group"), "G", 
+      N_("Next _Unread Group"), "G",
       NULL,
       G_CALLBACK(do_read_next_unread_group) },
 
     { "read-next-group", "ICON_READ_GROUP",
-      N_("Next _Group"), "<shift>G", 
+      N_("Next _Group"), "<shift>G",
       NULL,
       G_CALLBACK(do_read_next_group) },
 
@@ -485,7 +491,7 @@ namespace
       G_CALLBACK(do_read_next_article) },
 
     { "read-next-watched-article", NULL,
-      N_("Next _Watched Article"), "<control><shift>N", 
+      N_("Next _Watched Article"), "<control><shift>N",
       NULL,
       G_CALLBACK(do_read_next_watched_article) },
 
@@ -495,76 +501,76 @@ namespace
       G_CALLBACK(do_read_next_unread_thread) },
 
     { "read-next-thread", NULL,
-      N_("Next Threa_d"), "<control>T", 
+      N_("Next Threa_d"), "<control>T",
       NULL,
       G_CALLBACK(do_read_next_thread) },
 
     { "read-previous-article", NULL,
-      N_("Pre_vious Article"), "V", 
+      N_("Pre_vious Article"), "V",
       NULL,
       G_CALLBACK(do_read_previous_article) },
 
     { "read-previous-thread", NULL,
-      N_("Previous _Thread"), "<control>V", 
+      N_("Previous _Thread"), "<control>V",
       NULL,
 
       G_CALLBACK(do_read_previous_thread) },
     { "read-parent-article", NULL,
-      N_("_Parent Article"), "U", 
+      N_("_Parent Article"), "U",
       NULL,
       G_CALLBACK(do_read_parent_article) },
 
     { "plonk", NULL,
-      N_("Ignore _Author"), NULL, 
+      N_("Ignore _Author"), NULL,
       NULL,
       G_CALLBACK(do_plonk) },
     { "watch-thread", NULL,
-      N_("_Watch Thread"), NULL, 
+      N_("_Watch Thread"), NULL,
       NULL,
       G_CALLBACK(do_watch) },
 
     { "ignore-thread", NULL,
-      N_("_Ignore Thread"), NULL, 
+      N_("_Ignore Thread"), NULL,
       NULL,
       G_CALLBACK(do_ignore) },
 
     { "view-article-score", "ICON_SCORE",
-      N_("Edit Article's Watch/Ignore/Score..."), "<control><shift>C", 
+      N_("Edit Article's Watch/Ignore/Score..."), "<control><shift>C",
       NULL,
       G_CALLBACK(do_show_score_dialog) },
 
     { "add-article-score", "ICON_SCORE",
-      N_("Add a _Scoring Rule..."), "S", 
+      N_("Add a _Scoring Rule..."), "S",
       NULL,
       G_CALLBACK(do_show_new_score_dialog) },
 
     { "cancel-article", NULL,
-      N_("Cance_l Article..."), NULL, 
+      N_("Cance_l Article..."), NULL,
       NULL,
       G_CALLBACK(do_cancel_article) },
 
     { "supersede-article", NULL,
-      N_("_Supersede Article..."), NULL, 
+      N_("_Supersede Article..."), NULL,
       NULL,
       G_CALLBACK(do_supersede_article) },
 
     { "delete-article", GTK_STOCK_DELETE,
-      N_("_Delete Article"), "Delete", 
+      N_("_Delete Article"), "Delete",
       NULL,
       G_CALLBACK(do_delete_article) },
 
     { "clear-article-cache", NULL,
-      N_("Clear Article Cache"), NULL, 
+      N_("Clear Article Cache"), NULL,
       NULL,
       G_CALLBACK(do_clear_article_cache) },
 
     { "mark-article-read", "ICON_ARTICLE_READ",
-      N_("_Mark Article as Read"), "M", 
+      N_("_Mark Article as Read"), "M",
       NULL,
       G_CALLBACK(do_mark_article_read) },
 
     { "mark-article-unread", "ICON_ARTICLE_UNREAD",
-      N_("Mark Article as _Unread"), "<control>M", 
+      N_("Mark Article as _Unread"), "<control>M",
       NULL,
       G_CALLBACK(do_mark_article_unread) },
 
@@ -579,27 +585,27 @@ namespace
       G_CALLBACK(do_followup_to) },
 
     { "reply-to", NULL,
-      N_("_Reply to Author in Mail"), "R", 
+      N_("_Reply to Author in Mail"), "R",
       NULL,
       G_CALLBACK(do_reply_to) },
 
     { "pan-web-page", NULL,
-      N_("_Pan Home Page"), NULL, 
+      N_("_Pan Home Page"), NULL,
       NULL,
       G_CALLBACK(do_pan_web) },
 
     { "bug-report", NULL,
-      N_("Give _Feedback or Report a Bug..."), NULL, 
+      N_("Give _Feedback or Report a Bug..."), NULL,
       NULL,
       G_CALLBACK(do_bug_report) },
 
     { "tip-jar", NULL,
-      N_("_Tip Jar..."), NULL, 
+      N_("_Tip Jar..."), NULL,
       NULL,
       G_CALLBACK(do_tip_jar) },
 
     { "about-pan", GTK_STOCK_ABOUT,
-      N_("_About"), NULL, 
+      N_("_About"), NULL,
       NULL,
       G_CALLBACK(do_about_pan) }
   };
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 7743777..67b802f 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -63,6 +63,8 @@ extern "C" {
 #include "task-pane.h"
 #include "url.h"
 
+#include "profiles-dialog.h"
+
 namespace pan
 {
   void
@@ -192,7 +194,6 @@ GUI :: GUI (Data& data, Queue& queue, ArticleCache& cache, Prefs& prefs, GroupPr
   gtk_box_pack_start (GTK_BOX(_root), _menu_vbox, FALSE, FALSE, 0);
   gtk_widget_show (_menu_vbox);
 
-  //_group_pane = new GroupPane (*this, data, _prefs);
   _group_pane = new GroupPane (*this, data, _prefs);
   _header_pane = new HeaderPane (*this, data, _queue, _cache, _prefs, *this);
   _body_pane = new BodyPane (data, _cache, _prefs);
@@ -213,7 +214,7 @@ GUI :: GUI (Data& data, Queue& queue, ArticleCache& cache, Prefs& prefs, GroupPr
   gtk_container_add (GTK_CONTAINER(item), _header_pane->create_filter_entry());
   gtk_widget_show_all (GTK_WIDGET(item));
   gtk_toolbar_insert (GTK_TOOLBAR(toolbar), item, index+1);
-  
+
   //guint merge_id = gtk_ui_manager_new_merge_id (_ui_manager);
   //gtk_ui_manager_add_ui (_ui_manager, merge_id, path, "group-pane-filter", NULL, GTK_UI_MANAGER_TOOLITEM, true);
   //GtkWidget * item = gtk_ui_manager_get_widget (_ui_manager, path);
@@ -273,7 +274,7 @@ GUI :: GUI (Data& data, Queue& queue, ArticleCache& cache, Prefs& prefs, GroupPr
   gtk_box_pack_start (GTK_BOX(status_bar), _taskbar, true, true, 0);
   gtk_widget_show_all (status_bar);
 
-  // status 
+  // status
   w = _event_log_button = gtk_button_new ();
   gtk_widget_set_tooltip_text (w, _("Open the Event Log"));
   gtk_button_set_relief (GTK_BUTTON(w), GTK_RELIEF_NONE);
@@ -314,13 +315,13 @@ GUI :: GUI (Data& data, Queue& queue, ArticleCache& cache, Prefs& prefs, GroupPr
 
   gtk_accel_map_load (get_accel_filename().c_str());
 
-  { // make sure taskbar views have the right tasks in them -- 
+  { // make sure taskbar views have the right tasks in them --
     // when Pan first starts, the active tasks are already running
     Queue::task_states_t task_states;
-    queue.get_all_task_states(task_states);    
+    queue.get_all_task_states(task_states);
     foreach(Queue::tasks_t, task_states.tasks, it) {
       Queue::TaskState s = task_states.get_state(*it);
-      if (s == Queue::RUNNING || s == Queue::DECODING)
+      if (s == Queue::RUNNING || s == Queue::DECODING || s == Queue::ENCODING)
         on_queue_task_active_changed (queue, *(*it), true);
     }
   }
@@ -532,13 +533,13 @@ GUI :: prompt_user_for_save_path (GtkWindow * parent, const Prefs& prefs)
 std::string
 GUI :: prompt_user_for_filename (GtkWindow * parent, const Prefs& prefs)
 {
-	
+
   if (prev_path.empty())
     prev_path = prefs.get_string ("default-save-attachments-path", g_get_home_dir ());
   if (!file :: file_exists (prev_path.c_str()))
   prev_path = g_get_home_dir ();
     prev_file = std::string(_("Untitled.nzb"));
-    
+
   GtkWidget * w = gtk_file_chooser_dialog_new (_("Save NZB File as"),
 				      parent,
 				      GTK_FILE_CHOOSER_ACTION_SAVE,
@@ -548,7 +549,7 @@ GUI :: prompt_user_for_filename (GtkWindow * parent, const Prefs& prefs)
 	gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (w), TRUE);
 	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w), prev_path.c_str());
 	gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (w), prev_file.c_str());
-	
+
 	std::string file;
 	const int response (gtk_dialog_run (GTK_DIALOG(w)));
 	if (response == GTK_RESPONSE_ACCEPT) {
@@ -596,13 +597,12 @@ void GUI :: do_save_articles_to_nzb ()
       std::string emptystring;
       foreach_const (std::vector<Article>, copies, it)
         tasks.push_back (new TaskArticle (_data, _data, *it, _cache, _data, 0, TaskArticle::RAW,emptystring));
-    
-          // write them to a file
-          std::ofstream tmp(file.c_str());
-          if (tmp.good()) {
-            NZB :: nzb_to_xml_file (tmp, tasks); 
-            tmp.close();
-          }
+
+      // write them to a file
+      std::ofstream tmp(file.c_str());
+      if (tmp.good())
+        NZB :: nzb_to_xml_file (tmp, tasks);
+      tmp.close();
     }
 }
 
@@ -650,7 +650,7 @@ namespace
     }
 
     virtual ~SaveArticlesFromNZB() {}
-    
+
     virtual void on_progress_finished (Progress&, int status)
     {
       if (status == OK) {
@@ -765,7 +765,7 @@ namespace
       gtk_container_add (GTK_CONTAINER(w), new_child);
       gtk_widget_show (new_child);
     }
-  } 
+  }
 }
 
 void GUI :: on_log_entry_added (const Log::Entry& e)
@@ -920,6 +920,7 @@ void GUI :: do_read_more ()
                      : "read-next-unread-article");
   }
 }
+
 void GUI :: do_read_less ()
 {
   if (!_body_pane->read_less ())
@@ -1073,7 +1074,7 @@ void GUI :: do_supersede_article ()
   // did this user post the message?
   const char * sender (g_mime_message_get_sender (message));
   const bool user_posted_this (_data.has_from_header (sender));
-  
+
   if (!user_posted_this) {
     GtkWidget * w = gtk_message_dialog_new (
       get_window(_root),
@@ -1118,7 +1119,7 @@ void GUI :: do_supersede_article ()
   g_object_unref (content_object);
   g_object_unref (stream);
 
-  PostUI * post = PostUI :: create_window (0, _data, _queue, _data, _data, new_message, _prefs, _group_prefs);
+  PostUI * post = PostUI :: create_window (_root, _data, _queue, _data, _data, new_message, _prefs, _group_prefs);
   if (post)
   {
     gtk_widget_show_all (post->root());
@@ -1181,7 +1182,7 @@ void GUI :: do_cancel_article ()
   g_object_unref (stream);
   g_free (cancel_message);
 
-  PostUI * post = PostUI :: create_window (0, _data, _queue, _data, _data, cancel, _prefs, _group_prefs);
+  PostUI * post = PostUI :: create_window (_root, _data, _queue, _data, _data, cancel, _prefs, _group_prefs);
   if (post)
   {
     gtk_widget_show_all (post->root());
@@ -1262,7 +1263,7 @@ GUI :: do_post ()
   g_mime_message_set_mime_part (message, GMIME_OBJECT(part));
   g_object_unref (part);
 
-  PostUI * post = PostUI :: create_window (0, _data, _queue, _data, _data, message, _prefs, _group_prefs);
+  PostUI * post = PostUI :: create_window (_root, _data, _queue, _data, _data, message, _prefs, _group_prefs);
   if (post)
     gtk_widget_show_all (post->root());
   g_object_unref (message);
@@ -1272,7 +1273,7 @@ void GUI :: do_followup_to ()
 {
   GMimeMessage * message = _body_pane->create_followup_or_reply (false);
   if (message) {
-    PostUI * post = PostUI :: create_window(0, _data, _queue, _data, _data, message, _prefs, _group_prefs);
+    PostUI * post = PostUI :: create_window(_root, _data, _queue, _data, _data, message, _prefs, _group_prefs);
     if (post)
       gtk_widget_show_all (post->root());
     g_object_unref (message);
@@ -1282,7 +1283,7 @@ void GUI :: do_reply_to ()
 {
   GMimeMessage * message = _body_pane->create_followup_or_reply (true);
   if (message) {
-    PostUI * post = PostUI :: create_window (0, _data, _queue, _data, _data, message, _prefs, _group_prefs);
+    PostUI * post = PostUI :: create_window (_root, _data, _queue, _data, _data, message, _prefs, _group_prefs);
     if (post)
       gtk_widget_show_all (post->root());
     g_object_unref (message);
@@ -1395,7 +1396,7 @@ GUI :: notebook_page_switched_cb (GtkNotebook *, GtkNotebookPage *, gint page_nu
   }
   g_idle_add (grab_focus_idle, w);
 }
- 
+
 void GUI :: do_tabbed_layout (bool tabbed)
 {
   if (hpane) {
@@ -1726,7 +1727,7 @@ GUI :: refresh_connection_label ()
     g_snprintf (tip, sizeof(tip), "%s", str);
   }
   else if (active || idle)
-  { 
+  {
     typedef std::vector<Queue::ServerConnectionCounts> counts_t;
     counts_t counts;
     _queue.get_full_connection_counts (counts);
@@ -1865,8 +1866,9 @@ GUI :: on_queue_error (Queue&, const StringView& message)
 
 void
 GUI :: on_prefs_flag_changed (const StringView&, bool)
-{
-}
+{}
+
+
 void
 GUI :: on_prefs_string_changed (const StringView& key, const StringView& value)
 {
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index 006ed63..64eb6e9 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -22,8 +22,9 @@
 #include <pan/general/log.h>
 #include <pan/general/progress.h>
 #include <pan/data/article-cache.h>
+#include <pan/data/file-queue.h>
 #include <pan/tasks/queue.h>
-
+#include <pan/gui/group-pane.h>
 #include <pan/gui/action-manager.h>
 #include <pan/gui/pan-ui.h>
 #include <pan/gui/prefs.h>
@@ -104,6 +105,7 @@ namespace pan
       virtual void do_clear_body_pane ();
       virtual void do_read_selected_article ();
       virtual void do_read_more ();
+//      virtual void do_binpost ();
       virtual void do_read_less ();
       virtual void do_read_next_unread_group ();
       virtual void do_read_next_group ();
@@ -160,7 +162,7 @@ namespace pan
 
     public:
       static std::string prompt_user_for_save_path (GtkWindow * parent, const Prefs& prefs);
-	  static std::string prompt_user_for_filename  (GtkWindow * parent, const Prefs& prefs);
+      static std::string prompt_user_for_filename  (GtkWindow * parent, const Prefs& prefs);
 
     private: // Queue::Listener
       friend class Queue;
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index ab62206..38d9deb 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -130,7 +130,7 @@ namespace
                       const Quark         & message_id)
   {
     int offset (ICON_EMPTY);
-      
+
     if (queue.contains (message_id))
       offset = ICON_QUEUED;
     else if (cache.contains (message_id))
@@ -318,7 +318,7 @@ HeaderPane :: create_row (const EvolutionDateMaker & e,
 
   std::pair<mid_to_row_t::iterator,bool> result (_mid_to_row.insert (row));
   g_assert (result.second);
-  
+
   return row;
 }
 
@@ -687,7 +687,7 @@ HeaderPane :: on_tree_change (const Data::ArticleTree::Diffs& diffs)
     }
     _tree_store->insert_sorted (tmp);
   }
-     
+
   // reparent...
   if (do_thread && !diffs.reparented.empty()) {
     PanTreeStore::parent_to_children_t tmp;
@@ -919,7 +919,7 @@ HeaderPane :: on_button_pressed (GtkWidget * treeview, GdkEventButton *event, gp
     GtkTreeSelection * selection = gtk_tree_view_get_selection(tv);
     GtkTreePath *path;
     if (gtk_tree_view_get_path_at_pos (tv,
-                                       (gint) event->x, 
+                                       (gint) event->x,
                                        (gint) event->y,
                                        &path, NULL, NULL, NULL))
     {
@@ -1631,7 +1631,6 @@ HeaderPane :: HeaderPane (ActionManager       & action_manager,
   g_signal_connect (sel, "changed", G_CALLBACK(on_selection_changed), this);
   on_selection_changed (sel, this);
 
-
   g_signal_connect (w, "button-release-event", G_CALLBACK(on_button_pressed), this);
   g_signal_connect (w, "button-press-event", G_CALLBACK(on_button_pressed), this);
   g_signal_connect (w, "row-collapsed", G_CALLBACK(row_collapsed_cb), NULL);
@@ -1869,7 +1868,7 @@ namespace
 }
 
 /**
-*** 
+***
 **/
 
 void
diff --git a/pan/gui/pan-ui.h b/pan/gui/pan-ui.h
index 47c7ab5..29dcb4b 100644
--- a/pan/gui/pan-ui.h
+++ b/pan/gui/pan-ui.h
@@ -52,6 +52,7 @@ namespace pan
     virtual void do_clear_body_pane () = 0;
     virtual void do_read_selected_article () = 0;
     virtual void do_read_more () = 0;
+//    virtual void do_binpost () = 0;
     virtual void do_read_less () = 0;
     virtual void do_read_next_unread_group () = 0;
     virtual void do_read_next_group () = 0;
diff --git a/pan/gui/pan.ui.h b/pan/gui/pan.ui.h
index 6f40a1a..91aecac 100644
--- a/pan/gui/pan.ui.h
+++ b/pan/gui/pan.ui.h
@@ -74,6 +74,7 @@ const char * fallback_ui_file =
 "      </menu>\n"
 "    </menu>\n"
 "    <menu action='go-menu'>\n"
+//"      <menuitem action='binpost' />\n"
 "      <menuitem action='read-more' />\n"
 "      <menuitem action='read-less' />\n"
 "      <separator />\n"
@@ -157,6 +158,7 @@ const char * fallback_ui_file =
 "    <toolitem action='post'/>\n"
 "    <toolitem action='followup-to'/>\n"
 "    <separator />\n"
+//"    <toolitem action='binpost' />\n"
 "    <toolitem action='read-more' />\n"
 "    <toolitem action='read-next-unread-article' />\n"
 "    <toolitem action='read-next-unread-thread' />\n"
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 2b3940f..e308328 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -39,6 +39,7 @@ extern "C" {
 #include <pan/usenet-utils/message-check.h>
 #include <pan/usenet-utils/mime-utils.h>
 #include <pan/data/data.h>
+#include <pan/gui/gui.h>
 #include <pan/tasks/task-post.h>
 #include "e-charset-dialog.h"
 #include "pad.h"
@@ -123,7 +124,7 @@ PostUI :: set_spellcheck_enabled (bool enabled)
 ***/
 
 /**
- * get current the body.
+ * get the current body.
  * since Pan posts WYSIWYG, pull from the view's lines
  * rather than just using text_buffer_get_text(start,end)
  */
@@ -134,7 +135,7 @@ PostUI :: get_body () const
   GtkTextBuffer * buf (_body_buf);
   GtkTextView * view (GTK_TEXT_VIEW(_body_view));
   const bool wrap (_prefs.get_flag ("compose-wrap-enabled", false));
-  
+
   // walk through all the complete lines...
   GtkTextIter body_start, body_end, line_start, line_end;
   gtk_text_buffer_get_bounds (buf, &body_start, &body_end);
@@ -197,6 +198,7 @@ namespace
   void do_close    (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->close_window (); }
   void do_wrap     (GtkToggleAction * w, gpointer p) { static_cast<PostUI*>(p)->set_wrap_mode (gtk_toggle_action_get_active (w)); }
   void do_edit2    (GtkToggleAction * w, gpointer p) { static_cast<PostUI*>(p)->set_always_run_editor (gtk_toggle_action_get_active (w)); }
+  void do_add_files(GtkAction*, gpointer p)          { static_cast<PostUI*>(p)->add_files (); }
 
   GtkActionEntry entries[] =
   {
@@ -215,7 +217,8 @@ namespace
     { "paste", GTK_STOCK_PASTE, 0, 0, 0, G_CALLBACK(do_paste) },
     { "rot13", GTK_STOCK_REFRESH, N_("_Rot13"), 0, N_("Rot13 Selected Text"), G_CALLBACK(do_rot13) },
     { "run-editor", GTK_STOCK_JUMP_TO, N_("Run _Editor"), "<control>e", N_("Run Editor"), G_CALLBACK(do_edit) },
-    { "manage-profiles", GTK_STOCK_EDIT, N_("Edit P_osting Profiles"), 0, 0, G_CALLBACK(do_profiles) }
+    { "manage-profiles", GTK_STOCK_EDIT, N_("Edit P_osting Profiles"), 0, 0, G_CALLBACK(do_profiles) },
+    { "add-files", GTK_STOCK_OPEN, N_("Add _Files to Queue"), "<control>O", N_("Add Files to Queue"), G_CALLBACK(do_add_files) },
   };
 
   GtkToggleActionEntry toggle_entries[] =
@@ -317,7 +320,7 @@ PostUI :: rot13_selection ()
     gtk_text_buffer_insert (_body_buf, &start, str, strlen(str));
     g_free (str);
   }
-} 
+}
 
 namespace
 {
@@ -329,14 +332,14 @@ namespace
 }
 
 void
-PostUI :: close_window ()
+PostUI :: close_window (bool flag)
 {
-  bool destroy_flag (false);;
+  bool destroy_flag (false || flag);
 
   if (get_body() == _unchanged_body)
     destroy_flag = true;
 
-  else {
+  else if (!flag) {
     GtkWidget * d = gtk_message_dialog_new (
       GTK_WINDOW(_root),
       GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -365,6 +368,9 @@ PostUI :: close_window ()
 bool
 PostUI :: check_message (const Quark& server, GMimeMessage * msg)
 {
+
+  std::cerr<<"check message\n";
+
   MessageCheck :: unique_strings_t errors;
   MessageCheck :: Goodness goodness;
 
@@ -403,7 +409,7 @@ PostUI :: check_charset ()
   if (charset == "UTF-8")
     return true;
 
-  // Check if body can be posted in the selected charset 
+  // Check if body can be posted in the selected charset
   const std::string body (get_body ());
   char *tmp = g_convert (body.c_str(), -1, charset.c_str(), "UTF-8", NULL, NULL, NULL);
   if (tmp) {
@@ -421,7 +427,7 @@ PostUI :: check_charset ()
   char * msg = g_strdup_printf (_("Message uses characters not specified in charset '%s' - possibly use '%s' "), charset.c_str(), tmp);
   GtkWidget * d = gtk_message_dialog_new (GTK_WINDOW(_root),
                                           GTK_DIALOG_DESTROY_WITH_PARENT,
-                                          GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, 
+                                          GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE,
 										  NULL);
   HIG :: message_dialog_set_text (GTK_MESSAGE_DIALOG(d),
                            _("There were problems with this post."),
@@ -431,7 +437,7 @@ PostUI :: check_charset ()
   gtk_widget_destroy (d);
   g_free (tmp);
   g_free (msg);
-  
+
   return false;
 }
 
@@ -468,6 +474,14 @@ namespace
 }
 
 void
+PostUI :: add_files ()
+{
+  if (!check_charset())
+    return;
+  prompt_user_for_queueable_files (_file_queue, GTK_WINDOW (gtk_widget_get_toplevel(_root)), _prefs);
+}
+
+void
 PostUI :: send_now ()
 {
   if (!check_charset())
@@ -582,7 +596,7 @@ PostUI :: on_progress_error (Progress&, const StringView& message)
                                           GTK_DIALOG_DESTROY_WITH_PARENT,
                                           GTK_MESSAGE_ERROR,
                                           GTK_BUTTONS_CLOSE, "%s", message.to_string().c_str());
-  g_signal_connect_swapped (d, "response", 
+  g_signal_connect_swapped (d, "response",
                             G_CALLBACK(gtk_widget_destroy), d);
   gtk_widget_show (d);
 }
@@ -652,28 +666,43 @@ PostUI :: maybe_post_message (GMimeMessage * message)
   /**
   ***  Pop up a ``Posting'' Dialog...
   **/
-  GtkWidget * d = gtk_dialog_new_with_buttons (_("Posting Article"),
-                                               GTK_WINDOW(_root),
-                                               GTK_DIALOG_DESTROY_WITH_PARENT,
-                                               //GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                               NULL);
-  char buf[512];
-  g_snprintf (buf, sizeof(buf), "<b>%s</b>", _("Posting..."));
-  GtkWidget * w = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, "use-markup", TRUE, "label", buf, NULL));
-  GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(d));
-  gtk_box_pack_start (GTK_BOX(content), w, false, false, PAD_SMALL);
-  w = gtk_progress_bar_new ();
-  gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR(w), 0.05);
-  const guint tag = g_timeout_add (100, pulse_me, w);
-  gtk_box_pack_start (GTK_BOX(content), w, false, false, PAD_SMALL);
-  g_object_set_data_full (G_OBJECT(d), "progressbar-timeout-tag", GUINT_TO_POINTER(tag), remove_progress_tag);
-  _post_dialog = d;
-  g_signal_connect (_post_dialog, "destroy", G_CALLBACK(gtk_widget_destroyed), &_post_dialog);
-  gtk_widget_show_all (d);
-  _post_task = new TaskPost (server, message);
-  _post_task->add_listener (this);
-  
-  _queue.add_task (_post_task, Queue::TOP);
+  if(_file_queue_empty)
+  {
+    GtkWidget * d = gtk_dialog_new_with_buttons (_("Posting Article"),
+                                                 GTK_WINDOW(_root),
+                                                 GTK_DIALOG_DESTROY_WITH_PARENT,
+                                                 //GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                                 NULL);
+    char buf[512];
+    g_snprintf (buf, sizeof(buf), "<b>%s</b>", _("Posting..."));
+    GtkWidget * w = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, "use-markup", TRUE, "label", buf, NULL));
+    GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(d));
+    gtk_box_pack_start (GTK_BOX(content), w, false, false, PAD_SMALL);
+    w = gtk_progress_bar_new ();
+    gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR(w), 0.05);
+    const guint tag = g_timeout_add (100, pulse_me, w);
+    gtk_box_pack_start (GTK_BOX(content), w, false, false, PAD_SMALL);
+    g_object_set_data_full (G_OBJECT(d), "progressbar-timeout-tag", GUINT_TO_POINTER(tag), remove_progress_tag);
+    _post_dialog = d;
+    g_signal_connect (_post_dialog, "destroy", G_CALLBACK(gtk_widget_destroyed), &_post_dialog);
+    gtk_widget_show_all (d);
+  }
+
+  if (_file_queue_empty)
+  {
+    _post_task = new TaskPost (server, message);
+    _post_task->add_listener (this);
+    _queue.add_task (_post_task, Queue::TOP);
+  } else
+  {
+
+    _post_task = new TaskUpload (_file_queue,profile.posting_server,
+                                   new_message_from_ui(POSTING),0,TaskUpload::YENC);
+    _post_task->add_listener (this);
+    _queue.add_task (_post_task, Queue::BOTTOM);
+    close_window(true);
+  }
+
 
   /**
   ***  Maybe remember the charsets.
@@ -703,7 +732,7 @@ namespace
 		char *fname;
 		PostUI *pui;
 	} se_data;
-	
+
 	void child_watch_cb(GPid pid, gint status, gpointer data)
 	{
 		se_data *d=static_cast<se_data*>(data);
@@ -818,7 +847,7 @@ PostUI :: spawn_editor ()
 void PostUI::spawn_editor_dead(char *fname)
 {
 	GtkTextBuffer * buf (_body_buf);
-	
+
   // read the file contents back in
   std::string txt;
   if (file :: get_text_file_contents (fname, txt)) {
@@ -945,6 +974,9 @@ namespace
 GMimeMessage*
 PostUI :: new_message_from_ui (Mode mode)
 {
+
+  std::cerr<<" new message from ui\n";
+
   GMimeMessage * msg (g_mime_message_new (false));
 
   // headers from the ui: From
@@ -1132,8 +1164,8 @@ PostUI :: create_body_widget (GtkTextBuffer*& buf, GtkWidget*& view, const Prefs
   pango_layout_set_text (layout, s.c_str(), s.size());
   pango_layout_get_extents (layout, &r, 0);
   gtk_widget_set_size_request (view, PANGO_PIXELS(r.width), -1 );
- 
-  // set the rest of the text view's policy 
+
+  // set the rest of the text view's policy
   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
   gtk_text_view_set_editable (GTK_TEXT_VIEW(view), true);
   GtkWidget * scrolled_window = gtk_scrolled_window_new (NULL, NULL);
@@ -1160,6 +1192,7 @@ PostUI :: update_profile_combobox ()
   GtkComboBox * combo (GTK_COMBO_BOX (_from_combo));
   char * active_text = gtk_combo_box_get_active_text (combo);
 
+  std::cerr<<" update_profile combobox\n";
   // if there's not already a selection,
   // pull the default for the newsgroup
   if (!active_text)
@@ -1192,7 +1225,7 @@ PostUI :: update_profile_combobox ()
       sel_index = index;
     ++index;
   }
- 
+
   // ensure _something_ is selected...
   gtk_combo_box_set_active (combo, sel_index);
 
@@ -1364,7 +1397,7 @@ PostUI :: apply_profile_to_body ()
   {
     // scrub the attribution for UTF8 cleanness
     attribution = header_to_utf8 (attribution);
- 
+
     std::string::size_type pos = body.find (old_attribution);
     if (!old_attribution.empty() && (pos != std::string::npos))
       body.replace (pos, old_attribution.size(), attribution);
@@ -1484,6 +1517,11 @@ namespace
     static_cast<PostUI*>(user_data)->apply_profile ();
   }
 
+//  void on_filequeue_changed (GtkWidget*, gpointer data)
+//  {
+//    static_cast<PostUI*>(data)->update_filequeue_tab();
+//  }
+
   typedef std::map <std::string, std::string> str2str_t;
 
   struct SetMessageForeachHeaderData
@@ -1542,6 +1580,7 @@ PostUI :: set_message (GMimeMessage * message)
     g_object_unref (G_OBJECT(_message));
   _message = message;
 
+  std::cerr<<" set message \n";
   // update subject, newsgroups, to fields
   std::string s = utf8ize (g_mime_message_get_subject (message));
   gtk_entry_set_text (GTK_ENTRY(_subject_entry), s.c_str());
@@ -1565,7 +1604,7 @@ PostUI :: set_message (GMimeMessage * message)
   SetMessageForeachHeaderData data;
   const char *name, *value;
   GMimeHeaderIter iter;
-  
+
   if (message->mime_part && g_mime_header_list_get_stream (message->mime_part->headers)) {
     if (g_mime_header_list_get_iter (message->mime_part->headers, &iter)) {
       do {
@@ -1575,7 +1614,7 @@ PostUI :: set_message (GMimeMessage * message)
       } while (g_mime_header_iter_next (&iter));
     }
   }
-  
+
   if (g_mime_header_list_get_iter (GMIME_OBJECT (message)->headers, &iter)) {
     do {
       value = g_mime_header_iter_get_value (&iter);
@@ -1583,7 +1622,7 @@ PostUI :: set_message (GMimeMessage * message)
       set_message_foreach_header_func (name, value, &data);
     } while (g_mime_header_iter_next (&iter));
   }
-  
+
   s = utf8ize (data.visible_headers);
   gtk_text_buffer_set_text (_headers_buf, s.c_str(), -1);
   _hidden_headers = data.hidden_headers;
@@ -1650,6 +1689,7 @@ PostUI :: group_entry_changed_idle (gpointer ui_gpointer)
   PostUI * ui (static_cast<PostUI*>(ui_gpointer));
   std::string charset;
 
+  std::cerr<<" group entry changed idle\n";
   // find the first posting charset in the newsgroups in _groups_entry.
   const char * text = gtk_entry_get_text (GTK_ENTRY(ui->_groups_entry));
   StringView line(text), groupname;
@@ -1676,7 +1716,7 @@ PostUI :: group_entry_changed_cb (GtkEditable*, gpointer ui_gpointer)
   PostUI * ui (static_cast<PostUI*>(ui_gpointer));
   unsigned int& tag (ui->_group_entry_changed_idle_tag);
   if (!tag)
-    tag = g_timeout_add (2000, group_entry_changed_idle, ui);
+    tag = g_timeout_add (4000, group_entry_changed_idle, ui);
 }
 
 /***
@@ -1745,10 +1785,19 @@ PostUI :: create_main_tab ()
   // Subject
 
   ++row;
+  char str[512];
+  char tip[512];
+  g_snprintf (tip, sizeof(tip), _("The subject of the messsage can contain following regular expressions\n \
+                                  That are replaced automatically:\n \
+                                  $1 - File number of current file in queue\n\
+                                  $2 - Total queuesize\n\
+                                  $f - Filename\n\
+                                  $s - Filesize of current file"));
   g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("_Subject"));
   l = gtk_label_new_with_mnemonic (buf);
   gtk_label_set_use_markup (GTK_LABEL(l), true);
   gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
+  gtk_widget_set_tooltip_text (l, tip);
   gtk_table_attach (GTK_TABLE(t), l, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
 
   w = _subject_entry = gtk_entry_new ();
@@ -1758,6 +1807,7 @@ PostUI :: create_main_tab ()
   // Newsgroup
 
   ++row;
+  std::cerr<<" create main tab\n";
   g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("_Newsgroups"));
   l = gtk_label_new_with_mnemonic (buf);
   gtk_label_set_use_markup (GTK_LABEL(l), true);
@@ -1830,7 +1880,7 @@ PostUI :: create_extras_tab ()
   w = _followupto_entry = gtk_entry_new ();
   gtk_label_set_mnemonic_widget (GTK_LABEL(l), w);
   /* i18n: "poster" is a key used by many newsreaders.  probably safest to keep this key in english. */
-gtk_widget_set_tooltip_text (w, _("The newsgroups where replies to your message should go.  This is only needed if it differs from the \"Newsgroups\" header.\n\nTo direct all replies to your email address, use \"Followup-To: poster\""));
+  gtk_widget_set_tooltip_text (w, _("The newsgroups where replies to your message should go.  This is only needed if it differs from the \"Newsgroups\" header.\n\nTo direct all replies to your email address, use \"Followup-To: poster\""));
   gtk_table_attach (GTK_TABLE(t), w, 1, 2, row, row+1, fe, fill, 0, 0);
 
   //  Reply-To
@@ -1894,6 +1944,65 @@ gtk_widget_set_tooltip_text (w, _("The email account where mail replies to your
   return t;
 }
 
+// todo scroll,translations
+GtkWidget*
+PostUI :: create_filequeue_tab ()
+{
+  GtkWidget *w ;
+  GtkListStore *list_store;
+  GtkTreeIter   iter;
+  GtkCellRenderer *renderer;
+
+  GtkWidget * scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+//  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window),
+//                                       GTK_SHADOW_IN);
+//  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+//                                  GTK_POLICY_AUTOMATIC,
+//                                  GTK_POLICY_AUTOMATIC);
+//  gtk_box_pack_start(GTK_BOX(gtk_hbox_new(FALSE,1)),scrolled_window,TRUE,TRUE,2);
+
+  list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT);
+  w = _filequeue_store = gtk_tree_view_new_with_model (GTK_TREE_MODEL(list_store));
+
+//  gtk_container_add (GTK_CONTAINER (scrolled_window), w);
+
+  // add columns
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), -1,   "Filename", renderer,"text", 0,NULL);
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), -1,   "Size (kB)",renderer,"text", 1,NULL);
+
+  gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(w),TRUE);
+
+  return w;
+}
+
+void
+PostUI :: update_filequeue_tab()
+{
+  GtkWidget* w = _filequeue_store ;
+  GtkListStore    *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
+  GtkTreeIter      iter;
+
+    gtk_list_store_clear(store);
+
+    FileQueue::articles_it it = _file_queue.begin();
+    std::cerr<<" filequeue tab\n";
+    int i(0);
+
+    for (; it != _file_queue.end(); ++it, ++i )
+    {
+      gtk_list_store_append (store, &iter);
+      gtk_list_store_set (store, &iter,
+                        0, (*it).filename.str,
+                        1, (*it).byte_count,
+                        -1);
+    }
+
+    _file_queue_empty = (i == 0);
+
+}
+
 
 PostUI :: ~PostUI ()
 {
@@ -1929,7 +2038,9 @@ PostUI :: PostUI (GtkWindow    * parent,
   _message (0),
   _charset (DEFAULT_CHARSET),
   _group_entry_changed_id (0),
-  _group_entry_changed_idle_tag (0)
+  _group_entry_changed_idle_tag (0),
+  //binpost
+  _file_queue_empty(true)
 {
   g_assert (profiles.has_profiles());
   g_return_if_fail (message != 0);
@@ -1963,6 +2074,7 @@ PostUI :: PostUI (GtkWindow    * parent,
   GtkWidget * notebook = gtk_notebook_new ();
   gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_main_tab(), gtk_label_new_with_mnemonic(_("_Message")));
   gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_extras_tab(), gtk_label_new_with_mnemonic(_("More _Headers")));
+  gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_filequeue_tab(), gtk_label_new_with_mnemonic(_("File _Queue")));
   pan_box_pack_start_defaults (GTK_BOX(vbox), notebook);
 
   // remember this message, but don't put it in the text view yet.
@@ -1974,7 +2086,7 @@ PostUI :: PostUI (GtkWindow    * parent,
 }
 
 PostUI*
-PostUI :: create_window (GtkWindow    * parent,
+PostUI :: create_window (GtkWidget    * parent,
                          Data         & data,
                          Queue        & queue,
                          GroupServer  & gs,
@@ -2002,5 +2114,46 @@ PostUI :: create_window (GtkWindow    * parent,
       return 0;
   }
 
-  return new PostUI (parent, data, queue, gs, profiles, message, prefs, group_prefs);
+  return new PostUI (0, data, queue, gs, profiles, message, prefs, group_prefs);
 }
+
+void
+PostUI :: prompt_user_for_queueable_files (FileQueue& queue, GtkWindow * parent, const Prefs& prefs)
+{
+  std::string prev_path = prefs.get_string ("default-save-attachments-path", g_get_home_dir ());
+
+  GtkWidget * w = gtk_file_chooser_dialog_new (_("Add files to queue"),
+				      parent,
+				      GTK_FILE_CHOOSER_ACTION_OPEN,
+				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+				      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+				      NULL);
+	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w), prev_path.c_str());
+	gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (w), true);
+	gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (w), false);
+
+	const int response (gtk_dialog_run (GTK_DIALOG(w)));
+	if (response == GTK_RESPONSE_ACCEPT) {
+		GSList * tmp_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (w));
+		if (_file_queue_empty) _file_queue_empty=!_file_queue_empty;
+		GSList * cur = g_slist_nth (tmp_list,0);
+    const Profile profile (get_current_profile ());
+    const StringView subject(gtk_entry_get_text (GTK_ENTRY(_subject_entry)));
+    struct stat stat_buf;
+
+    for (; cur; cur = cur->next)
+		{
+		  const StringView filename((char*)cur->data);
+		  stat(filename.str,&stat_buf);
+
+      _file_queue.add(subject, StringView(profile.username),
+                      filename, (unsigned int)stat_buf.st_size/1024, 0, FileQueue::END); //kB
+		}
+  	g_slist_free (tmp_list);
+  }
+	gtk_widget_destroy (w);
+	update_filequeue_tab();
+}
+
+
+
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index f879d14..b5d15ed 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -22,6 +22,7 @@
 
 #include <gmime/gmime-message.h>
 #include <pan/gui/prefs.h>
+#include <pan/data/file-queue.h>
 #include <pan/general/progress.h>
 #include <pan/tasks/queue.h>
 #include <pan/usenet-utils/text-massager.h>
@@ -39,9 +40,11 @@ namespace pan
   class PostUI: private Progress::Listener
   {
     public:
-      static PostUI* create_window (GtkWindow*, Data&, Queue&, GroupServer&, Profiles&,
+      static PostUI* create_window (GtkWidget*, Data&, Queue&, GroupServer&, Profiles&,
                                     GMimeMessage*, Prefs&, GroupPrefs&);
-    
+
+      void prompt_user_for_queueable_files (FileQueue& queue, GtkWindow * parent, const Prefs& prefs);
+
     protected:
       PostUI (GtkWindow*, Data&, Queue&, GroupServer&, Profiles&,
               GMimeMessage*, Prefs&, GroupPrefs&);
@@ -60,9 +63,11 @@ namespace pan
       void open_draft ();
       void prompt_for_charset ();
       void send_now ();
-      void close_window ();
+      void add_files ();
+      void close_window (bool flag=false);
       void set_wrap_mode (bool wrap);
       void set_always_run_editor (bool);
+      void update_filequeue_tab();
 
     private:
       void done_sending_message (GMimeMessage*, bool);
@@ -90,6 +95,9 @@ namespace pan
       GtkWidget * _from_combo;
       GtkWidget * _subject_entry;
       GtkWidget * _groups_entry;
+
+      GtkWidget * _filequeue_store;
+
       GtkWidget * _to_entry;
       GtkWidget * _followupto_entry;
       GtkWidget * _replyto_entry;
@@ -106,12 +114,17 @@ namespace pan
       std::string _current_signature;
       GtkWidget * _post_dialog;
       TaskPost * _post_task;
+      TaskUpload * _upload_task;
       typedef std::map<std::string, std::string> str2str_t;
       str2str_t _hidden_headers;
       str2str_t _profile_headers;
       std::string _unchanged_body;
       int _wrap_pixels;
 
+      /* binpost */
+      bool _file_queue_empty;
+      FileQueue _file_queue;
+
     private:
       void add_actions (GtkWidget* box);
       void apply_profile_to_body ();
@@ -125,6 +138,7 @@ namespace pan
     private:
       GtkWidget* create_main_tab ();
       GtkWidget* create_extras_tab ();
+      GtkWidget* create_filequeue_tab ();
 
     private:
       std::string utf8ize (const StringView&) const;
@@ -142,7 +156,7 @@ namespace pan
 
     public:
       void set_spellcheck_enabled (bool);
-	  void spawn_editor_dead(char *);
+      void spawn_editor_dead(char *);
 
   };
 }
diff --git a/pan/gui/post.ui.h b/pan/gui/post.ui.h
index 95a76d1..3b7eab0 100644
--- a/pan/gui/post.ui.h
+++ b/pan/gui/post.ui.h
@@ -1,4 +1,4 @@
-const char * fallback_post_ui = 
+const char * fallback_post_ui =
 "<ui>\n"
 "  <menubar name='post'>\n"
 "    <menu action='file-menu'>\n"
@@ -38,6 +38,8 @@ const char * fallback_post_ui =
 "    <separator />\n"
 "    <toolitem action='rot13' />\n"
 "    <toolitem action='run-editor' />\n"
+"    <separator />\n"
+"    <toolitem action='add-files' />\n"
 "  </toolbar>\n"
 "\n"
 "</ui>\n";
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index 15237a4..ffca9d9 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -53,6 +53,7 @@ namespace
     GtkWidget * auth_password_entry;
     GtkWidget * connection_limit_spin;
     GtkWidget * expiration_age_combo;
+    GtkWidget * xzver_compression_combo;
     GtkWidget * rank_combo;
     ServerEditDialog (Data& d, Queue& q): data(d), queue(q) {}
   };
@@ -216,10 +217,10 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
   ***  workarea
   **/
 
-  int row (0);
-  GtkWidget * t (HIG::workarea_create ());
-  gtk_box_pack_start (GTK_BOX( gtk_dialog_get_content_area( GTK_DIALOG(d->dialog))), t, TRUE, TRUE, 0);
-  HIG::workarea_add_section_title (t, &row, _("Location"));
+    int row (0);
+    GtkWidget * t (HIG::workarea_create ());
+    gtk_box_pack_start (GTK_BOX( gtk_dialog_get_content_area( GTK_DIALOG(d->dialog))), t, TRUE, TRUE, 0);
+    HIG::workarea_add_section_title (t, &row, _("Location"));
     HIG::workarea_add_section_spacer (t, row, 2);
 
     GtkWidget * w = d->address_entry = gtk_entry_new ();
@@ -231,8 +232,8 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
     gtk_widget_set_tooltip_text( w, _("The news server's port number.  Typically 119."));
     HIG::workarea_add_row (t, &row, _("Por_t:"), w, NULL);
 
-  HIG::workarea_add_section_divider (t, &row);
-  HIG::workarea_add_section_title (t, &row, _("Login (if Required)"));
+    HIG::workarea_add_section_divider (t, &row);
+    HIG::workarea_add_section_title (t, &row, _("Login (if Required)"));
     HIG::workarea_add_section_spacer (t, row, 2);
 
     w = d->auth_username_entry = gtk_entry_new ();
@@ -244,15 +245,17 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
     HIG::workarea_add_row (t, &row, _("_Password:"), w, NULL);
     gtk_widget_set_tooltip_text( w, _("The password to give the server when asked.  If your server doesn't require authentication, you can leave this blank."));
 
-  HIG::workarea_add_section_divider (t, &row);
-  HIG::workarea_add_section_title (t, &row, _("Settings"));
+    HIG::workarea_add_section_divider (t, &row);
+    HIG::workarea_add_section_title (t, &row, _("Settings"));
     HIG::workarea_add_section_spacer (t, row, 2);
 
+    // max connections
     const int DEFAULT_MAX_PER_SERVER (4);
     a = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 0.0, DEFAULT_MAX_PER_SERVER, 1.0, 1.0, 0.0));
     d->connection_limit_spin = w = gtk_spin_button_new (GTK_ADJUSTMENT(a), 1.0, 0u);
     HIG::workarea_add_row (t, &row, _("Connection _Limit:"), w, NULL);
 
+    // expiration
     struct { int type; const char * str; } items[] = {
       { 14,  N_("After Two Weeks") },
       { 31,  N_("After One Month") },
@@ -275,6 +278,7 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
     gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
     HIG::workarea_add_row (t, &row, _("E_xpire Old Articles:"), w, NULL);
 
+    //rank
     struct { int rank; const char * str; } rank_items[] = {
       { 1, N_("Primary") },
       { 2, N_("Fallback") }
@@ -298,6 +302,25 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
     gtk_widget_set_tooltip_text( e, _("Fallback servers are used for articles that can't be found on the primaries.  One common approach is to use free servers as primaries and subscription servers as fallbacks."));
     HIG::workarea_add_row (t, &row, e, w);
 
+    /* xzver settings */
+    struct { int type; const char * str; } xzver_options[] = {
+      { 0,  N_("No") },
+      { 1,  N_("Yes") }
+    };
+    store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+    for (unsigned int i(0); i<G_N_ELEMENTS(xzver_options); ++i) {
+      GtkTreeIter iter;
+      gtk_list_store_append (store,  &iter);
+      gtk_list_store_set (store, &iter, 0, _(xzver_options[i].str), 1, xzver_options[i].type, -1);
+    }
+    d->xzver_compression_combo = w = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+    g_object_unref (G_OBJECT(store));
+    GtkCellRenderer * renderer2 (gtk_cell_renderer_text_new ());
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer2, TRUE);
+    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer2, "text", 0, NULL);
+    gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
+    HIG::workarea_add_row (t, &row, _("Serverside _Header-compression support:"), w, NULL);
+
   d->server = server;
   edit_dialog_populate (data, server, d);
   gtk_widget_show_all (d->dialog);
@@ -416,7 +439,7 @@ namespace
                                               GtkDialogFlags(GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT),
                                               GTK_MESSAGE_QUESTION,
                                               GTK_BUTTONS_NONE,
-                                              _("Really delete \"%s\"?"), 
+                                              _("Really delete \"%s\"?"),
                                               addr.c_str());
       gtk_dialog_add_buttons (GTK_DIALOG(w),
                               GTK_STOCK_NO, GTK_RESPONSE_NO,
@@ -470,7 +493,7 @@ namespace
   void
   server_tree_view_row_activated_cb (GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, gpointer user_data)
   {
-    edit_button_clicked_cb (NULL, user_data);	
+    edit_button_clicked_cb (NULL, user_data);
   }
 
   void
@@ -513,7 +536,7 @@ pan :: server_list_dialog_new (Data& data, Queue& queue, GtkWindow* parent)
   gtk_tree_view_append_column (GTK_TREE_VIEW (d->server_tree_view), column);
   GtkTreeSelection * selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (d->server_tree_view));
   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-	
+
   // add callbacks
   g_signal_connect (GTK_TREE_VIEW (d->server_tree_view), "row-activated",
                     G_CALLBACK (server_tree_view_row_activated_cb), d->dialog);
diff --git a/pan/gui/task-pane.cc b/pan/gui/task-pane.cc
index 15066e5..8c8c0aa 100644
--- a/pan/gui/task-pane.cc
+++ b/pan/gui/task-pane.cc
@@ -208,11 +208,11 @@ TaskPane :: update_status (const task_states_t& tasks)
   {
     Task * task (*it);
     const Queue::TaskState state (tasks.get_state (task));
-    if (state == Queue::RUNNING || state == Queue::DECODING)
+    if (state == Queue::RUNNING || state == Queue::DECODING || state == Queue::ENCODING)
       ++running_count;
     else if (state == Queue::STOPPED)
       ++stopped_count;
-    else if (state == Queue::QUEUED || state == Queue::QUEUED_FOR_DECODE)
+    else if (state == Queue::QUEUED || state == Queue::QUEUED_FOR_DECODE || state == Queue::QUEUED_FOR_ENCODE)
       ++queued_count;
 
     if (state==Queue::RUNNING || state==Queue::QUEUED)
@@ -225,7 +225,7 @@ TaskPane :: update_status (const task_states_t& tasks)
     g_snprintf (buf, sizeof(buf), _("Pan: Tasks (%d Queued, %d Running, %d Stopped)"), queued_count, running_count, stopped_count);
   else if (running_count || queued_count)
     g_snprintf (buf, sizeof(buf), _("Pan: Tasks (%d Queued, %d Running)"), queued_count, running_count);
-  else 
+  else
     g_snprintf (buf, sizeof(buf), _("Pan: Tasks"));
   gtk_window_set_title (GTK_WINDOW(_root), buf);
 
diff --git a/pan/tasks/Makefile.am b/pan/tasks/Makefile.am
index 46a6ea1..a1b5b3d 100644
--- a/pan/tasks/Makefile.am
+++ b/pan/tasks/Makefile.am
@@ -4,11 +4,13 @@ noinst_LIBRARIES = libtasks.a
 
 libtasks_a_SOURCES = \
   decoder.cc \
+  encoder.cc \
   task.cc \
   task-article.cc \
   task-groups.cc \
   task-post.cc \
   task-xover.cc \
+  task-upload.cc \
   nntp.cc \
   nzb.cc \
   queue.cc \
@@ -21,12 +23,14 @@ noinst_HEADERS = \
   adaptable-set.cc \
   adaptable-set.h \
   decoder.h \
+  encoder.h \
   defgroup.h \
   health.h \
   task.h \
   task-article.h \
   task-groups.h \
   task-post.h \
+  task-upload.h \
   task-weak-ordering.h \
   task-xover.h \
   nntp.h  \
diff --git a/pan/tasks/nntp.cc b/pan/tasks/nntp.cc
index d097667..c2378dc 100644
--- a/pan/tasks/nntp.cc
+++ b/pan/tasks/nntp.cc
@@ -333,6 +333,23 @@ NNTP :: write_next_command ()
 ***/
 
 void
+NNTP :: xzver (const Quark   & group,
+               uint64_t        low,
+               uint64_t        high,
+               Listener      * l)
+{
+   _listener = l;
+
+   if (group != _group)
+      _commands.push_back (build_command ("GROUP %s\r\n", group.c_str()));
+
+   _commands.push_back (build_command ("XZVER %"G_GUINT64_FORMAT"-%"G_GUINT64_FORMAT"\r\n", low, high));
+
+   write_next_command ();
+}
+
+
+void
 NNTP :: xover (const Quark   & group,
                uint64_t        low,
                uint64_t        high,
diff --git a/pan/tasks/nntp.h b/pan/tasks/nntp.h
index 20e3adf..b8ebd99 100644
--- a/pan/tasks/nntp.h
+++ b/pan/tasks/nntp.h
@@ -134,6 +134,12 @@ namespace pan
                              uint64_t             high,
                              Listener           * l);
 
+      /* same as above, experimental header compression (!!!) */
+      void xzver            (const Quark        & group,
+                             uint64_t             low,
+                             uint64_t             high,
+                             Listener           * l);
+
       /**
        * Executes a LIST command: "LIST"
        *
diff --git a/pan/tasks/queue.cc b/pan/tasks/queue.cc
index 25503c5..ce9de63 100644
--- a/pan/tasks/queue.cc
+++ b/pan/tasks/queue.cc
@@ -42,7 +42,9 @@ Queue :: Queue (ServerInfo         & server_info,
   _socket_creator (socket_creator),
   _worker_pool (pool),
   _decoder (pool),
+  _encoder (pool),
   _decoder_task (0),
+  _encoder_task (0),
   _save_delay_secs (save_delay_secs),
   _needs_saving (false),
   _last_time_saved (0),
@@ -200,6 +202,8 @@ Queue :: get_task_counts (int& active, int& total)
     active_tasks.insert (it->second);
   if (_decoder_task)
     active_tasks.insert (_decoder_task);
+  if (_encoder_task)
+    active_tasks.insert (_encoder_task);
   active = active_tasks.size ();
   total = _tasks.size ();
 }
@@ -215,6 +219,16 @@ Queue :: give_task_a_decoder (Task * task)
 }
 
 void
+Queue :: give_task_a_encoder (Task * task)
+{
+  const bool was_active (task_is_active (task));
+  _encoder_task = task;
+  if (!was_active)
+    fire_task_active_changed (task, true);
+  task->give_encoder (this, &_encoder); // it's active now...
+}
+
+void
 Queue :: give_task_a_connection (Task * task, NNTP * nntp)
 {
   const bool was_active (task_is_active (task));
@@ -264,6 +278,12 @@ Queue :: process_task (Task * task)
     if (!_decoder_task)
       give_task_a_decoder (task);
   }
+  else if (state._work == Task::NEED_ENCODER)
+  {
+    if (!_encoder_task)
+      give_task_a_encoder (task);
+  }
+
   else while (_is_online && (state._work == Task::NEED_NNTP))
   {
     // make the requests...
@@ -302,6 +322,20 @@ Queue :: find_first_task_needing_decoder ()
 }
 
 Task*
+Queue :: find_first_task_needing_encoder ()
+{
+  foreach (TaskSet, _tasks, it) {
+    const Task::State& state ((*it)->get_state ());
+    if  ((state._work == Task::NEED_ENCODER)
+      && (!_stopped.count (*it))
+      && (!_removing.count (*it)))
+      return *it;
+  }
+
+  return 0;
+}
+
+Task*
 Queue :: find_first_task_needing_server (const Quark& server)
 {
   foreach (TaskSet, _tasks, it) {
@@ -664,6 +698,30 @@ Queue :: check_in (Decoder* decoder UNUSED, Task* task)
 }
 
 void
+Queue :: check_in (Encoder* decoder UNUSED, Task* task)
+{
+  // take care of our decoder counting...
+  _encoder_task = 0;
+
+  // notify the listeners if the task isn't active anymore...
+  if (!task_is_active (task))
+    fire_task_active_changed (task, false);
+
+  // if the task hit an error, fire an error message
+  const Task::State state (task->get_state ());
+  if (state._health == ERR_LOCAL)
+    fire_queue_error ("");
+
+  // pass our worker thread on to another task
+  Task * next = find_first_task_needing_encoder ();
+  if (next && (next!=task))
+    process_task (next);
+
+  // what to do now with this task...
+  process_task (task);
+}
+
+void
 Queue :: move_up (const tasks_t& tasks)
 {
   foreach_const (tasks_t, tasks, it) {
@@ -786,11 +844,11 @@ Queue :: get_stats (unsigned long   & queued_count,
     Task * task (*it);
 
     const Queue::TaskState state (tasks.get_state (task));
-    if (state == Queue::RUNNING || state == Queue::DECODING)
+    if (state == Queue::RUNNING || state == Queue::DECODING || state == Queue::ENCODING)
       ++running_count;
     else if (state == Queue::STOPPED)
       ++stopped_count;
-    else if (state == Queue::QUEUED || state == Queue::QUEUED_FOR_DECODE)
+    else if (state == Queue::QUEUED || state == Queue::QUEUED_FOR_DECODE || state == Queue::QUEUED_FOR_ENCODE)
       ++queued_count;
 
     if (state==Queue::RUNNING || state==Queue::QUEUED)
diff --git a/pan/tasks/queue.h b/pan/tasks/queue.h
index 09b97ef..008ee7e 100644
--- a/pan/tasks/queue.h
+++ b/pan/tasks/queue.h
@@ -26,6 +26,7 @@
 #include <pan/general/macros.h> // for UNUSED
 #include <pan/general/map-vector.h>
 #include <pan/tasks/decoder.h>
+#include <pan/tasks/encoder.h>
 #include <pan/general/quark.h>
 #include <pan/tasks/nntp-pool.h>
 #include <pan/tasks/socket.h>
@@ -60,6 +61,7 @@ namespace pan
   class Queue:
     public NNTP::Source,
     public Task::DecoderSource,
+    public Task::EncoderSource,
     private NNTP_Pool::Listener,
     private AdaptableSet<Task*, TaskWeakOrdering>::Listener
   {
@@ -98,11 +100,11 @@ namespace pan
         ServerConnectionCounts(): active(0), idle(0), connecting(0), KiBps(0.0) {}
       };
       void get_full_connection_counts (std::vector<ServerConnectionCounts>& setme) const;
-                                         
+
 
     public:
-      enum TaskState { QUEUED, RUNNING, DECODING, STOPPED, REMOVING,
-                       QUEUED_FOR_DECODE };
+      enum TaskState { QUEUED, RUNNING, DECODING, ENCODING, STOPPED, REMOVING,
+                       QUEUED_FOR_DECODE, QUEUED_FOR_ENCODE};
 
       /**
        * An ordered collection of tasks and their corresponding TaskState s.
@@ -116,15 +118,19 @@ namespace pan
           sorted_tasks_t _running;
           sorted_tasks_t _removing;
           sorted_tasks_t _need_decode;
+          sorted_tasks_t _need_encode;
           Task * _decoding;
+          Task * _encoding;
         public:
           tasks_t tasks;
           TaskState get_state (Task* task) const {
             if (_decoding && (task==_decoding)) return DECODING;
+            if (_decoding && (task==_encoding)) return ENCODING;
             if (_removing.count(task)) return REMOVING;
             if (_stopped.count(task)) return STOPPED;
             if (_running.count(task)) return RUNNING;
             if (_need_decode.count(task)) return QUEUED_FOR_DECODE;
+            if (_need_encode.count(task)) return QUEUED_FOR_ENCODE;
             if (_queued.count(task)) return QUEUED;
             return STOPPED;
           }
@@ -162,8 +168,9 @@ namespace pan
     public: // inherited from NNTP::Source
       virtual void check_in (NNTP*, Health);
 
-    public: // inherited from Task::DecoderSource
+    public: // inherited from Task::De/EncoderSource
       virtual void check_in (Decoder*, Task*);
+      virtual void check_in (Encoder*, Task*);
 
     private: // inherited from NNTP_Pool::Listener
       virtual void on_pool_has_nntp_available (const Quark& server);
@@ -172,11 +179,13 @@ namespace pan
     protected:
       void process_task (Task *);
       void give_task_a_decoder (Task*);
+      void give_task_a_encoder (Task*);
       void give_task_a_connection (Task*, NNTP*);
       ServerInfo& _server_info;
       bool _is_online;
       Task* find_first_task_needing_server (const Quark& server);
       Task* find_first_task_needing_decoder ();
+      Task* find_first_task_needing_encoder ();
       bool find_best_server (const Task::State::unique_servers_t& servers, Quark& setme);
       bool task_is_active (const Task*) const;
 
@@ -188,7 +197,9 @@ namespace pan
       Socket::Creator * _socket_creator;
       WorkerPool & _worker_pool;
       Decoder _decoder;
+      Encoder _encoder;
       Task * _decoder_task;
+      Task * _encoder_task;
 
     protected:
       virtual void fire_tasks_added  (int index, int count);
diff --git a/pan/tasks/task-article.cc b/pan/tasks/task-article.cc
index 3c77f7b..e529d52 100644
--- a/pan/tasks/task-article.cc
+++ b/pan/tasks/task-article.cc
@@ -132,7 +132,7 @@ TaskArticle :: ~TaskArticle ()
   // ensure our on_worker_done() doesn't get called after we're dead
   if (_decoder)
       _decoder->cancel_silently();
-  
+
   _cache.release (_article.get_part_mids());
 }
 
@@ -291,7 +291,7 @@ TaskArticle :: on_nntp_done  (NNTP             * nntp,
       }
       break;
   }
-  
+
   update_work (nntp);
   check_in (nntp, health);
 }
diff --git a/pan/tasks/task-post.cc b/pan/tasks/task-post.cc
index 18e7747..d605d18 100644
--- a/pan/tasks/task-post.cc
+++ b/pan/tasks/task-post.cc
@@ -57,6 +57,7 @@ TaskPost :: use_nntp (NNTP * nntp)
   _state.set_working ();
 
   char * text = g_mime_object_to_string (GMIME_OBJECT(_message));
+  std::cerr<<text<<std::endl;
   nntp->post (text, this);
   g_free (text);
 }
diff --git a/pan/tasks/task.cc b/pan/tasks/task.cc
index 82680d6..397e3c7 100644
--- a/pan/tasks/task.cc
+++ b/pan/tasks/task.cc
@@ -70,11 +70,26 @@ Task :: give_decoder (DecoderSource* s, Decoder* d)
   _decoder_to_source[d] = s;
   use_decoder (d);
 }
+
+void
+Task :: give_encoder (EncoderSource* s, Encoder* d)
+{
+  _encoder_to_source[d] = s;
+  use_encoder (d);
+}
+
 void
 Task :: use_decoder (Decoder * d UNUSED)
 {
   abort ();
 }
+
+void
+Task :: use_encoder (Encoder * d UNUSED)
+{
+  abort ();
+}
+
 void
 Task :: check_in (Decoder * d)
 {
@@ -87,3 +102,16 @@ Task :: check_in (Decoder * d)
     s->check_in (d, this);
   }
 }
+
+void
+Task :: check_in (Encoder * d)
+{
+  encoder_to_source_t::iterator it (_encoder_to_source.find (d));
+
+  if (it != _encoder_to_source.end())
+  {
+    EncoderSource * s (it->second);
+    _encoder_to_source.erase (d);
+    s->check_in (d, this);
+  }
+}
diff --git a/pan/tasks/task.h b/pan/tasks/task.h
index 5865fdf..b1138d6 100644
--- a/pan/tasks/task.h
+++ b/pan/tasks/task.h
@@ -30,6 +30,7 @@
 namespace pan
 {
    class Decoder;
+   class Encoder;
 
    /**
     * Base class for jobs that require NNTP interaction to be completed.
@@ -52,8 +53,9 @@ namespace pan
             COMPLETED,
             /** Task is waiting on an nntp connection */
             NEED_NNTP,
-            /** Task waiting for a decoder */
+            /** Task waiting for a decoder/encoder */
             NEED_DECODER,
+            NEED_ENCODER,
             /** Task is running */
             WORKING
          };
@@ -92,6 +94,9 @@ namespace pan
                void set_need_decoder () {
                    _work = NEED_DECODER; _servers.clear(); }
 
+               void set_need_encoder () {
+                   _work = NEED_ENCODER; _servers.clear(); }
+
                void set_health (Health h) {
                   _health = h; }
 
@@ -109,10 +114,16 @@ namespace pan
            virtual ~DecoderSource() {}
            virtual void check_in (Decoder*, Task*) = 0;
          };
+         struct EncoderSource {
+           virtual ~EncoderSource() {}
+           virtual void check_in (Encoder*, Task*) = 0;
+         };
 
          /** Loan the task a Decoder */
          void give_decoder (DecoderSource*, Decoder*);
 
+         void give_encoder (EncoderSource*, Encoder*);
+
       public:
 
          Task (const Quark& type, const StringView& description);
@@ -138,8 +149,10 @@ namespace pan
          int get_nntp_count () const { return _nntp_to_source.size(); }
 
          virtual void use_decoder (Decoder*);
+         virtual void use_encoder (Encoder*);
 
          void check_in (Decoder*);
+         void check_in (Encoder*);
 
       private:
 
@@ -151,10 +164,11 @@ namespace pan
          /** used in check_in() to remember where the nntp is to be returned */
          nntp_to_source_t _nntp_to_source;
 
-         /** typedef for _decoder_to_source */
          typedef Loki::AssocVector<Decoder*,DecoderSource*> decoder_to_source_t;
-         /** used in check_in() to remember where the decoder is to be returned */
+         typedef Loki::AssocVector<Encoder*,EncoderSource*> encoder_to_source_t;
+         /** used in check_in() to remember where the decoder/encoder is to be returned */
          decoder_to_source_t _decoder_to_source;
+         encoder_to_source_t _encoder_to_source;
    };
 }
 
diff --git a/uulib/uuencode.c b/uulib/uuencode.c
index a629073..73dbbc2 100644
--- a/uulib/uuencode.c
+++ b/uulib/uuencode.c
@@ -57,7 +57,7 @@
 #endif
 #endif
 
-char * uuencode_id = "$Id$";
+char * uuencode_id = "$Id: uuencode.c,v 1.22 2002/04/02 10:04:52 fp Exp $";
 
 #if 0
 /*
@@ -135,7 +135,7 @@ unsigned char UUEncodeTable[64] = {
   'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
   'X', 'Y', 'Z', '[', '\\',']', '^', '_'
 };
-  
+
 
 unsigned char B64EncodeTable[64] = {
   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
@@ -162,11 +162,11 @@ unsigned char XXEncodeTable[64] = {
 unsigned char BHEncodeTable[64] = {
   '!', '"', '#', '$', '%', '&', '\'', '(',
   ')', '*', '+', ',', '-', '0', '1', '2',
-  '3', '4', '5', '6', '8', '9', '@', 'A', 
-  'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 
-  'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 
-  'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[', 
-  '`', 'a', 'b', 'c', 'd', 'e', 'f', 'h', 
+  '3', '4', '5', '6', '8', '9', '@', 'A',
+  'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+  'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
+  'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[',
+  '`', 'a', 'b', 'c', 'd', 'e', 'f', 'h',
   'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r'
 };
 
@@ -242,11 +242,11 @@ char *uuestr_otemp;
  * Encode one part of the data stream
  */
 
-static int 
+static int
 UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc32_t *crc, crc32_t *pcrc)
 {
-  unsigned char *itemp = (unsigned char *) uuestr_itemp;
-  unsigned char *otemp = (unsigned char *) uuestr_otemp;
+  unsigned char *itemp = (char *) uuestr_itemp;
+  unsigned char *otemp = (char *) uuestr_otemp;
   unsigned char *optr, *table, *tptr;
   int index, count;
   long line=0;
@@ -267,12 +267,12 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
 
   if (encoding == PT_ENCODED || encoding == QP_ENCODED) {
     while (!feof (infile) && (linperfile <= 0 || line < linperfile)) {
-      if (_FP_fgets ((char*)itemp, 255, infile) == NULL) {
+      if (_FP_fgets (itemp, 255, infile) == NULL) {
 	break;
       }
 
       itemp[255] = '\0';
-      count = strlen ((char*)itemp);
+      count = strlen (itemp);
 
       llen = 0;
       optr = otemp;
@@ -280,7 +280,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
       /*
        * Busy Callback
        */
-      
+
       if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
 	UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
 		   uustring (S_ENCODE_CANCEL));
@@ -292,10 +292,10 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
 	 * If there is a line feed, replace by eolstring
 	 */
 	if (count > 0 && itemp[count-1] == '\n') {
-          const size_t n = strlen ((char*) eolstring);
 	  itemp[--count] = '\0';
 	  if (fwrite (itemp, 1, count, outfile) != count ||
-	      fwrite ((char *) eolstring, 1, n, outfile) != n) {
+	      fwrite ((char *) eolstring, 1,
+		      strlen(eolstring), outfile) != strlen (eolstring)) {
 	    return UURET_IOERR;
 	  }
 	}
@@ -341,7 +341,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
 
 	    if (fwrite (otemp, 1, llen, outfile) != llen ||
 		fwrite ((char *) eolstring, 1,
-			strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
+			strlen(eolstring), outfile) != strlen (eolstring)) {
 	      return UURET_IOERR;
 	    }
 
@@ -357,7 +357,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
 
 	      if (fwrite (otemp, 1, 3, outfile) != 3 ||
 		  fwrite ((char *) eolstring, 1,
-			  strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
+			  strlen(eolstring), outfile) != strlen (eolstring)) {
 		return UURET_IOERR;
 	      }
 	    }
@@ -386,13 +386,13 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
 
 	    *optr++ = '=';
 	    llen++;
-	    
+
 	    if (fwrite (otemp, 1, llen, outfile) != llen ||
 		fwrite ((char *) eolstring, 1,
-			strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
+			strlen(eolstring), outfile) != strlen (eolstring)) {
 	      return UURET_IOERR;
 	    }
-	    
+
 	    optr = otemp;
 	    llen = 0;
 	  }
@@ -433,7 +433,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
       /*
        * Busy Callback
        */
-      
+
       if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
 	UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
 		   uustring (S_ENCODE_CANCEL));
@@ -444,7 +444,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
 	if (llen > 127) {
 	  if (fwrite (otemp, 1, llen, outfile) != llen ||
 	      fwrite ((char *) eolstring, 1,
-		      strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
+		      strlen(eolstring), outfile) != strlen (eolstring)) {
 	    return UURET_IOERR;
 	  }
 	  llen = 0;
@@ -490,7 +490,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
     if (llen) {
       if (fwrite (otemp, 1, llen, outfile) != llen ||
 	  fwrite ((char *) eolstring, 1,
-		  strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
+		  strlen(eolstring), outfile) != strlen (eolstring)) {
 	return UURET_IOERR;
       }
     }
@@ -563,7 +563,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
       if (encoding == B64ENCODED) {
 	if (count - index == 2) {
 	  *optr++ = table[itemp[index] >> 2];
-	  *optr++ = table[((itemp[index  ] & 0x03) << 4) | 
+	  *optr++ = table[((itemp[index  ] & 0x03) << 4) |
 			  ((itemp[index+1] & 0xf0) >> 4)];
 	  *optr++ = table[((itemp[index+1] & 0x0f) << 2)];
 	  *optr++ = '=';
@@ -579,7 +579,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc3
       else if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
 	if (count - index == 2) {
 	  *optr++ = table[itemp[index] >> 2];
-	  *optr++ = table[((itemp[index  ] & 0x03) << 4) | 
+	  *optr++ = table[((itemp[index  ] & 0x03) << 4) |
 			  ( itemp[index+1] >> 4)];
 	  *optr++ = table[((itemp[index+1] & 0x0f) << 2)];
 	  *optr++ = table[0];
@@ -630,7 +630,7 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
   crc32_t crc;
   crc32_t *crcptr=NULL;
 
-  if (outfile==NULL || 
+  if (outfile==NULL ||
       (infile == NULL && infname==NULL) ||
       (outfname==NULL && infname==NULL) ||
       (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
@@ -717,7 +717,7 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
   if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
     fprintf (outfile, "begin %o %s%s",
 	     (themode) ? themode : 0644,
-	     UUFNameFilter ((outfname)?outfname:infname), 
+	     UUFNameFilter ((outfname)?outfname:infname),
 	     eolstring);
   }
   else if (encoding == YENC_ENCODED) {
@@ -725,13 +725,13 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
     crcptr = &crc;
     if (progress.fsize == -1) {
       fprintf (outfile, "=ybegin line=128 name=%s%s",
-	       UUFNameFilter ((outfname)?outfname:infname), 
+	       UUFNameFilter ((outfname)?outfname:infname),
 	       eolstring);
     }
     else {
       fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
 	       progress.fsize,
-	       UUFNameFilter ((outfname)?outfname:infname), 
+	       UUFNameFilter ((outfname)?outfname:infname),
 	       eolstring);
     }
   }
@@ -748,8 +748,8 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
   }
 
   if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
-    fprintf (outfile, "%c%s",    
-	     (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], 
+    fprintf (outfile, "%c%s",
+	     (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
 	     eolstring);
     fprintf (outfile, "end%s", eolstring);
   }
@@ -793,7 +793,7 @@ UUEncodePartial (FILE *outfile, FILE *infile,
 {
   mimemap *miter=mimetable;
   static FILE *theifile;
-  int themode, numparts=1;
+  int themode, numparts;
   struct stat finfo;
   long thesize;
   char *ptr;
@@ -832,7 +832,7 @@ UUEncodePartial (FILE *outfile, FILE *infile,
       }
       if (linperfile <= 0)
 	numparts = 1;
-      else 
+      else
 	numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
 			  (linperfile*bpl[encoding]));
 
@@ -902,7 +902,7 @@ UUEncodePartial (FILE *outfile, FILE *infile,
     }
 
     fprintf (outfile, "%s", eolstring);
-    
+
     /*
      * for the first part of UU or XX messages, print a begin line
      */
@@ -920,33 +920,33 @@ UUEncodePartial (FILE *outfile, FILE *infile,
       if (progress.totsize == -1) {
 	fprintf (outfile, "=ybegin part=%d line=128 name=%s%s",
 		 partno,
-		 UUFNameFilter ((outfname)?outfname:infname), 
+		 UUFNameFilter ((outfname)?outfname:infname),
 		 eolstring);
       }
       else {
 	fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s",
 		 partno,
 		 progress.totsize,
-		 UUFNameFilter ((outfname)?outfname:infname), 
+		 UUFNameFilter ((outfname)?outfname:infname),
 		 eolstring);
       }
 
-      fprintf (outfile, "=ypart begin=%ld end=%ld%s",
+      fprintf (outfile, "=ypart begin=%d end=%d%s",
 	       (partno-1)*linperfile*128+1,
-	       (partno*linperfile*128) < progress.totsize ? 
+	       (partno*linperfile*128) < progress.totsize ?
 	       (partno*linperfile*128) : progress.totsize,
 	       eolstring);
     }
     else {
       if (progress.totsize == -1) {
 	fprintf (outfile, "=ybegin line=128 name=%s%s",
-		 UUFNameFilter ((outfname)?outfname:infname), 
+		 UUFNameFilter ((outfname)?outfname:infname),
 		 eolstring);
       }
       else {
 	fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
 		 progress.totsize,
-		 UUFNameFilter ((outfname)?outfname:infname), 
+		 UUFNameFilter ((outfname)?outfname:infname),
 		 eolstring);
       }
     }
@@ -990,21 +990,21 @@ UUEncodePartial (FILE *outfile, FILE *infile,
 
   if (feof (theifile) &&
       (encoding == UU_ENCODED || encoding == XX_ENCODED)) {
-    fprintf (outfile, "%c%s",    
-	     (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], 
+    fprintf (outfile, "%c%s",
+	     (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
 	     eolstring);
     fprintf (outfile, "end%s", eolstring);
   }
   else if (encoding == YENC_ENCODED) {
     if (numparts != 1) {
-      fprintf (outfile, "=yend size=%ld part=%d pcrc32=%08lx",
-	       (partno*linperfile*128) < progress.totsize ? 
+      fprintf (outfile, "=yend size=%d part=%d pcrc32=%08lx",
+	       (partno*linperfile*128) < progress.totsize ?
 	       linperfile*128 : (progress.totsize-(partno-1)*linperfile*128),
 	       partno,
 	       pcrc);
     }
     else {
-      fprintf (outfile, "=yend size=%ld",
+      fprintf (outfile, "=yend size=%d",
 	       progress.totsize);
     }
     if (feof (theifile))
@@ -1112,7 +1112,7 @@ UUEncodeToStream (FILE *outfile, FILE *infile,
   if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
     fprintf (outfile, "begin %o %s%s",
 	     (themode) ? themode : 0644,
-	     UUFNameFilter ((outfname)?outfname:infname), 
+	     UUFNameFilter ((outfname)?outfname:infname),
 	     eolstring);
   }
   else if (encoding == YENC_ENCODED) {
@@ -1120,13 +1120,13 @@ UUEncodeToStream (FILE *outfile, FILE *infile,
     crcptr = &crc;
     if (progress.fsize == -1) {
       fprintf (outfile, "=ybegin line=128 name=%s%s",
-	       UUFNameFilter ((outfname)?outfname:infname), 
+	       UUFNameFilter ((outfname)?outfname:infname),
 	       eolstring);
     }
     else {
       fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
 	       progress.fsize,
-	       UUFNameFilter ((outfname)?outfname:infname), 
+	       UUFNameFilter ((outfname)?outfname:infname),
 	       eolstring);
     }
   }
@@ -1135,7 +1135,7 @@ UUEncodeToStream (FILE *outfile, FILE *infile,
     if (res != UURET_CANCEL) {
       UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
 		 uustring (S_ERR_ENCODING),
-		 UUFNameFilter ((infname)?infname:outfname), 
+		 UUFNameFilter ((infname)?infname:outfname),
 		 (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res));
     }
     progress.action = 0;
@@ -1143,8 +1143,8 @@ UUEncodeToStream (FILE *outfile, FILE *infile,
   }
 
   if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
-    fprintf (outfile, "%c%s",    
-	     (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], 
+    fprintf (outfile, "%c%s",
+	     (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
 	     eolstring);
     fprintf (outfile, "end%s", eolstring);
   }
@@ -1212,7 +1212,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
       sprintf (oname, "%s", diskname);
     }
     else {
-      len = ((uusavepath)?strlen(uusavepath):0) + strlen (diskname) 
+      len = ((uusavepath)?strlen(uusavepath):0) + strlen (diskname)
 	+ ((uuencodeext)?strlen(uuencodeext):0) + 5;
 
       if ((oname = malloc (len)) == NULL) {
@@ -1224,7 +1224,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
     }
   }
   else {
-    len = ((uusavepath) ? strlen (uusavepath) : 0) + 
+    len = ((uusavepath) ? strlen (uusavepath) : 0) +
       strlen(UUFNameFilter(infname)) +
 	((uuencodeext)?strlen(uuencodeext):0) + 5;
 
@@ -1234,7 +1234,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
       return UURET_NOMEM;
     }
     optr = UUFNameFilter (infname);
-    sprintf (oname, "%s%s", 
+    sprintf (oname, "%s%s",
 	     (uusavepath)?uusavepath:"",
 	     (*optr=='.')?optr+1:optr);
   }
@@ -1275,7 +1275,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
     }
     if (linperfile <= 0)
       numparts = 1;
-    else 
+    else
       numparts = (int) (((long)finfo.st_size + (linperfile*bpl[encoding]-1)) /
 			(linperfile*bpl[encoding]));
 
@@ -1313,7 +1313,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
      */
     if (progress.numparts==1 && progress.totsize!=-1 && uuencodeext!=NULL)
       strcpy  (optr, uuencodeext);
-    else 
+    else
       sprintf (optr, "%03d", part);
 
     /*
@@ -1380,7 +1380,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
     if (part==1 && (encoding == UU_ENCODED || encoding == XX_ENCODED)) {
       fprintf (outfile, "begin %o %s%s",
 	       (filemode)?filemode : 0644,
-	       UUFNameFilter ((outfname)?outfname:infname), 
+	       UUFNameFilter ((outfname)?outfname:infname),
 	       eolstring);
     }
     else if (encoding == YENC_ENCODED) {
@@ -1394,33 +1394,33 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
 	if (progress.totsize == -1) {
 	  fprintf (outfile, "=ybegin part=%d line=128 name=%s%s",
 		   part,
-		   UUFNameFilter ((outfname)?outfname:infname), 
+		   UUFNameFilter ((outfname)?outfname:infname),
 		   eolstring);
 	}
 	else {
 	  fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s",
 		   part,
 		   progress.totsize,
-		   UUFNameFilter ((outfname)?outfname:infname), 
+		   UUFNameFilter ((outfname)?outfname:infname),
 		   eolstring);
 	}
 
-	fprintf (outfile, "=ypart begin=%ld end=%ld%s",
+	fprintf (outfile, "=ypart begin=%d end=%d%s",
 		 (part-1)*linperfile*128+1,
-		 (part*linperfile*128) < progress.totsize ? 
+		 (part*linperfile*128) < progress.totsize ?
 		 (part*linperfile*128) : progress.totsize,
 		 eolstring);
       }
       else {
 	if (progress.totsize == -1) {
 	  fprintf (outfile, "=ybegin line=128 name=%s%s",
-		   UUFNameFilter ((outfname)?outfname:infname), 
+		   UUFNameFilter ((outfname)?outfname:infname),
 		   eolstring);
 	}
 	else {
 	  fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
 		   progress.totsize,
-		   UUFNameFilter ((outfname)?outfname:infname), 
+		   UUFNameFilter ((outfname)?outfname:infname),
 		   eolstring);
 	}
       }
@@ -1431,7 +1431,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
       if (res != UURET_CANCEL) {
 	UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
 		   uustring (S_ERR_ENCODING),
-		   UUFNameFilter ((infname)?infname:outfname),	 
+		   UUFNameFilter ((infname)?infname:outfname),
 		   (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res));
       }
       if (infile==NULL) fclose (theifile);
@@ -1444,25 +1444,25 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
 
     if (feof (theifile) &&
 	(encoding == UU_ENCODED || encoding == XX_ENCODED)) {
-      fprintf (outfile, "%c%s",    
-	       (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], 
+      fprintf (outfile, "%c%s",
+	       (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
 	       eolstring);
       fprintf (outfile, "end%s", eolstring);
     }
     else if (encoding == YENC_ENCODED) {
       if (numparts != 1) {
-	fprintf (outfile, "=yend size=%ld part=%d pcrc32=%08lx",
-		 (part*linperfile*128) < progress.totsize ? 
+	fprintf (outfile, "=yend size=%d part=%d pcrc32=%08lx",
+		 (part*linperfile*128) < progress.totsize ?
 		 linperfile*128 : (progress.totsize-(part-1)*linperfile*128),
 		 part,
 		 pcrc);
       }
       else {
-	fprintf (outfile, "=yend size=%ld",
+	fprintf (outfile, "=yend size=%d",
 		 progress.totsize);
       }
       if (feof (theifile))
-	fprintf (outfile, " crc32=%08lx", crc); 
+	fprintf (outfile, " crc32=%08lx", crc);
       fprintf (outfile, "%s", eolstring);
     }
 
@@ -1585,7 +1585,7 @@ UUE_PrepSingleExt (FILE *outfile, FILE *infile,
 
   res = UUEncodeToStream (outfile, infile, infname, encoding,
 			  outfname, filemode);
-  
+
   _FP_free (subline);
   return res;
 }
@@ -1657,7 +1657,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
       }
       if (linperfile <= 0)
 	numparts = 1;
-      else 
+      else
 	numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
 			  (linperfile*bpl[encoding]));
 
@@ -1738,7 +1738,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
   }
   else {
     if (subject)
-      sprintf (subline, "%s (%03d/%03d) - [ %s ]", 
+      sprintf (subline, "%s (%03d/%03d) - [ %s ]",
 	       subject, partno, numparts, oname);
     else
       sprintf (subline, "[ %s ] (%03d/%03d)",
@@ -1768,7 +1768,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
     fprintf (outfile, "\tid=\"%s\"%s",
 	     mimeid, eolstring);
   }
-    
+
   fprintf (outfile, "%s", eolstring);
 
   res = UUEncodePartial (outfile, theifile,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]