[pan2/testing: 92/279] buggy ...



commit 2bdc68d59d93993168ff8856fd630f11c338ac4b
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date:   Tue Jun 7 11:30:32 2011 +0200

    buggy ...

 pan/data/encode-cache.cc |   85 ++++++++++-------------
 pan/data/encode-cache.h  |    1 +
 pan/data/encode-cache.o  |  Bin 495716 -> 889992 bytes
 pan/gui/gui.cc           |    2 +-
 pan/gui/post-ui.cc       |   81 +++++++++++++---------
 pan/gui/post-ui.h        |    4 +-
 pan/tasks/encoder.cc     |   97 +++++++++++++++++++++-----
 pan/tasks/encoder.h      |    9 ++-
 pan/tasks/nzb.cc         |  121 ++++++++++++++++++++++++---------
 pan/tasks/nzb.h          |    2 +
 pan/tasks/task-upload.cc |  129 ++++++++++++++++------------------
 pan/tasks/task-upload.h  |   17 +++--
 uulib/uudeview.h         |    6 +-
 uulib/uuencode.c         |  172 ++++++++++++++++++++++++----------------------
 14 files changed, 427 insertions(+), 299 deletions(-)
---
diff --git a/pan/data/encode-cache.cc b/pan/data/encode-cache.cc
index d9bd86e..1de3acf 100644
--- a/pan/data/encode-cache.cc
+++ b/pan/data/encode-cache.cc
@@ -56,7 +56,6 @@ namespace
    {
       int partno();
       g_snprintf (buf, sizeof(buf), "%s.%d", mid.c_str(), partno);
-      std::cerr<<"ec mid to fn "<<buf<<"\n";
       return buf;
    }
 
@@ -97,7 +96,6 @@ namespace
       *out = '\0';
 
       return out - buf;
-      std::cerr<<"ec fn to mid "<<(out-buf)<<"\n";
    }
 };
 
@@ -119,32 +117,27 @@ EncodeCache :: EncodeCache (const StringView& path, size_t max_megs):
    }
    else
    {
-
-
-     ///TODO import articles, see nzb.ccc
-//      char filename[PATH_MAX];
-//      const char * fname;
-//      while ((fname = g_dir_read_name (dir)))
-//      {
-//         struct stat stat_p;
-//         g_snprintf (filename, sizeof(filename), "%s%c%s", _path.c_str(), G_DIR_SEPARATOR, fname);
-//         if (!stat (filename, &stat_p))
-//         {
-//            char str[2048];
-//            const int len (filename_to_message_id (str, sizeof(str), fname));
-//            if (len != 0)
-//            {
-//               MsgInfo info;
-//               info._message_id = StringView (str, len);
-//               info._size = stat_p.st_size;
-//               info._date = stat_p.st_mtime;
-////               _current_bytes += info._size;
-//               _mid_to_info.insert (mid_to_info_t::value_type (info._message_id, info));
-//            }
-//         }
-//      }
-//      g_dir_close (dir);
-//      debug ("loaded " << _mid_to_info.size() << " articles into cache from " << _path);
+      char filename[PATH_MAX];
+      const char * fname;
+      while ((fname = g_dir_read_name (dir)))
+      {
+         struct stat stat_p;
+         g_snprintf (filename, sizeof(filename), "%s%c%s", _path.c_str(), G_DIR_SEPARATOR, fname);
+         std::cerr<<"loaded "<<filename<<std::endl;
+         if (!stat (filename, &stat_p))
+         {
+           MsgInfo info;
+           info._message_id = filename;
+           info._size = stat_p.st_size;
+           info._date = stat_p.st_mtime;
+           _current_bytes += info._size;
+           _mid_to_info.insert (mid_to_info_t::value_type (info._message_id, info));
+         }
+      }
+      g_dir_close (dir);
+      std::cerr <<"loaded " << _mid_to_info.size() << " articles into encode-cache from "
+      << _path<<", size is : "<<_current_bytes<<" , max is "<<_max_megs * 1024 * 1024<<std::endl;
+      if (_current_bytes>_max_megs*1024*1024) resize();
    }
 }
 
@@ -186,15 +179,11 @@ EncodeCache :: get_filename (char* buf, const Quark& mid) const
    const char* base = g_path_get_basename(mid.c_str());
    g_snprintf (buf, PATH_MAX, "%s%c%s", _path.c_str(), G_DIR_SEPARATOR, base);
    g_free((gpointer)base);
-   std::cerr<<"ec get_filename "<<buf<<"\n";
 }
 
-///TODO give function a reference to vector!!
 FILE*
 EncodeCache :: get_fp_from_mid(const Quark& mid)
 {
-  std::cerr<<"ec get_fp from mid "<<mid.c_str()<<"\n";
-  std::cerr<<"mid to info : "<<_mid_to_info[mid]._message_id<<std::endl;
   return _mid_to_info[mid]._fp;
 }
 
@@ -202,34 +191,27 @@ FILE*
 EncodeCache :: add (const Quark& message_id)
 {
 
-  std::cerr<<"ec add "<<message_id<<"\n";
-
   pan_return_val_if_fail (!message_id.empty(), false);
 
   FILE * fp = 0;
   char filename[PATH_MAX];
-  struct stat sb;
   get_filename (filename, message_id);
+  std::cerr<<"cache add "<<filename<<std::endl;
   fp = fopen (filename, "wb+");
 
   if (!fp)
   {
     Log::add_err_va (_("Unable to save \"%s\" %s"),
                      filename, file::pan_strerror(errno));
-  }
-  else
+  } else
   {
-    std::cerr<<"building msginfo\n";
     MsgInfo info;
     info._fp = fp;
     info._message_id = message_id;
-    stat (message_id, &sb);
-    info._size = sb.st_size;
+    info._size = 0;
     info._date = time(0);
-    _current_bytes += info._size;
     _mid_to_info.insert (mid_to_info_t::value_type (info._message_id, info));
-    fire_added (message_id);
-    resize ();
+
   }
   return fp;
 }
@@ -238,10 +220,20 @@ EncodeCache :: add (const Quark& message_id)
 ****
 ***/
 
+void EncodeCache :: finalize (const Quark& message_id)
+{
+  struct stat sb;
+  FILE * fp = get_fp_from_mid(message_id);
+  if (fp) fclose(fp);
+  stat (message_id, &sb);
+  _mid_to_info[message_id]._size = sb.st_size;
+  fire_added (message_id);
+  _current_bytes += sb.st_size;
+}
+
 void
 EncodeCache :: reserve (const mid_sequence_t& mids)
 {
-  std::cerr<<"ec reserve\n";
   foreach_const (mid_sequence_t, mids, it)
     ++_locks[*it];
 }
@@ -249,7 +241,7 @@ EncodeCache :: reserve (const mid_sequence_t& mids)
 void
 EncodeCache :: release (const mid_sequence_t& mids)
 {
-  std::cerr<<"ec release\n";
+  std::cerr<<"ec release"<<std::endl;
   foreach_const (mid_sequence_t, mids, it)
     if (!--_locks[*it])
       _locks.erase (*it);
@@ -282,8 +274,6 @@ EncodeCache :: get_data(std::string& data, const Quark& where)
   get_filename(buf, where);
   std::ifstream in(buf, std::ifstream::in);
   std::stringstream out;
-  if (in.bad())
-    std::cerr<<"error getting file "<<where.c_str()<<std::endl;
   while (in.good())
     out << (char) in.get();
 
@@ -313,7 +303,6 @@ EncodeCache :: resize (guint64 max_bytes)
         unlink (buf);
         _current_bytes -= it->_size;
         removed.insert (mid);
-        if (_mid_to_info[mid]._fp) fclose(_mid_to_info[mid]._fp);
         _mid_to_info.erase (mid);
       }
     }
diff --git a/pan/data/encode-cache.h b/pan/data/encode-cache.h
index de39479..68ede69 100644
--- a/pan/data/encode-cache.h
+++ b/pan/data/encode-cache.h
@@ -62,6 +62,7 @@ namespace pan
 
       bool contains (const Quark& message_id) const;
       FILE* add (const Quark& message_id);
+      void finalize (const Quark& message_id);
       void get_data(std::string& data, const Quark& where);
       void reserve (const mid_sequence_t& mids);
       void release (const mid_sequence_t& mids);
diff --git a/pan/data/encode-cache.o b/pan/data/encode-cache.o
index d0b69c0..710d05b 100644
Binary files a/pan/data/encode-cache.o and b/pan/data/encode-cache.o differ
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index f8e60f1..a242685 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -600,7 +600,7 @@ void GUI :: do_save_articles_to_nzb ()
 
       // write them to a file
       std::ofstream tmp(file.c_str());
-          if (tmp.good())
+      if (tmp.good())
         NZB :: nzb_to_xml_file (tmp, tasks);
       tmp.close();
     }
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index c0da668..514e7cb 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -245,10 +245,10 @@ namespace
       N_("Clear List"),
       G_CALLBACK(do_clear_list) },
 
-    { "select-parts", NULL,
-      N_("Select needed Parts"), "",
-      N_("Select needed Parts"),
-      G_CALLBACK(do_select_parts) },
+//    { "select-parts", NULL,
+//      N_("Select needed Parts"), "",
+//      N_("Select needed Parts"),
+//      G_CALLBACK(do_select_parts) },
 
     { "move-up", NULL,
       N_("Move Up"), "",
@@ -2020,9 +2020,6 @@ PostUI :: create_filequeue_tab ()
   w = add_button (buttons, GTK_STOCK_DELETE, G_CALLBACK(delete_clicked_cb), this);
   gtk_widget_set_tooltip_text( w, _("Delete from Queue"));
   gtk_box_pack_start (GTK_BOX(buttons), gtk_vseparator_new(), 0, 0, 0);
-  add_button (buttons, GTK_STOCK_SELECT_ALL, 0, 0);
-  w = gtk_toggle_button_new_with_label(_("Save"));
-  gtk_box_pack_start (GTK_BOX(vbox), w, false, false, 0);
   pan_box_pack_start_defaults (GTK_BOX(buttons), gtk_event_box_new());
 
   gtk_box_pack_start (GTK_BOX(vbox), buttons, false, false, 0);
@@ -2080,13 +2077,12 @@ PostUI:: on_parts_box_clicked_cb (GtkCellRendererToggle *cell, gchar *path_str,
 
   enabled ^= 1;
   if (enabled==0)
-    data->upload_ptr()->needed().erase(part);
+    data->upload_ptr()->_needed.erase(part);
   else
   {
     TaskUpload::Needed tmp;
     tmp.partno = part;
-    tmp.partial = true;
-    data->upload_ptr()->needed().insert(std::pair<int, TaskUpload::Needed>(part,tmp));
+    data->upload_ptr()->_needed.insert(std::pair<int, TaskUpload::Needed>(part,tmp));
 
   }
   gtk_list_store_set(GTK_LIST_STORE( model ), &iter, 1, false, -1);
@@ -2168,11 +2164,9 @@ PostUI :: create_parts_tab ()
   l = gtk_label_new (NULL);
   gtk_table_attach (GTK_TABLE(t), l, 0, 2, row, row+1, fe, fill, 0, 0);
 
-  //7
-  ++row;
-
-  // 8
+  // 7
   //treeview for parts list
+  ++row;
   w = _parts_store = gtk_tree_view_new_with_model (GTK_TREE_MODEL(gtk_list_store_new (3,  G_TYPE_UINT, G_TYPE_BOOLEAN, G_TYPE_STRING)));
 
   // add columns
@@ -2191,8 +2185,7 @@ PostUI :: create_parts_tab ()
   gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(w),TRUE);
   gtk_tree_view_columns_autosize(GTK_TREE_VIEW(w));
 
-  ++row;
-  gtk_table_attach (GTK_TABLE(t), w, 1, 2, row, row+1, fe, fill, 0, 0);
+  gtk_table_attach (GTK_TABLE(t), w, 0, 2, row, row+1, fe, fill, 0, 0);
 
   //append scroll window
   w = gtk_scrolled_window_new (NULL, NULL);
@@ -2332,7 +2325,7 @@ PostUI :: remove_files (void)
 }
 
 
-
+///TODO!!
 void
 PostUI :: move_up (void)
 {
@@ -2385,11 +2378,6 @@ void PostUI :: delete_clicked_cb (GtkButton*, PostUI* pane)
   pane->remove_files ();
 }
 
-//void PostUI :: save_clicked_cb (GtkButton*, Postui* pane)
-//{
-//  pane->
-//}
-
 
 void
 PostUI :: update_filequeue_tab()
@@ -2445,11 +2433,10 @@ PostUI :: select_parts ()
   g_signal_connect (_part_select, "delete-event", G_CALLBACK(delete_parts_cb), this);
   gtk_window_set_role (GTK_WINDOW(w), "pan-parts-window");
   gtk_window_set_title (GTK_WINDOW(w), _("Select Parts"));
-  int x,h;
-  x = 350;
-  h = 650;
-  gtk_window_set_default_size (GTK_WINDOW(w), x, h);
-
+  int x,y;
+  x = _prefs.get_int("post-ui-width", -1);
+  y = _prefs.get_int("post-ui-height", 450);
+  gtk_window_set_default_size (GTK_WINDOW(_root), x, y);
   // populate the window
   GtkWidget * vbox = gtk_vbox_new (false, PAD_SMALL);
   gtk_container_add (GTK_CONTAINER(w), vbox);
@@ -2597,6 +2584,9 @@ PostUI :: create_window (GtkWindow    * parent,
 void
 PostUI :: prompt_user_for_queueable_files (tasks_v& queue, GtkWindow * parent, const Prefs& prefs)
 {
+  char buf[4096];
+  struct stat sb;
+
   const Profile profile (get_current_profile ());
   GMimeMessage * message (new_message_from_ui (POSTING));
   if (!check_message(profile.posting_server, message))
@@ -2642,15 +2632,38 @@ PostUI :: prompt_user_for_queueable_files (tasks_v& queue, GtkWindow * parent, c
         groups.insert(groupname);
     }
 
-    int i(0);
-    for (; cur; cur = cur->next, ++i)
+    int cnt(1);
+    for (; cur; cur = cur->next, ++cnt)
 		{
-		  _uploaded.push_back(new Article());
-		  Article& a(*_uploaded.back());
+		  Article a;
+		  a.subject = subject;
+		  a.author = author;
+      stat ((const char*)cur->data,&sb);
+      int total = (int) (((long)sb.st_size + (4000*128-1)) / (4000*128));
+
+      char* basename = g_path_get_basename((const char*)cur->data);
+      TaskUpload::needed_t import;
+      TaskUpload::Needed n;
+      foreach_const (quarks_t, groups, git)
+         n.xref.insert (profile.posting_server, *git,0);
+      for (int i = 1; i <= total; ++i)
+      {
+        g_snprintf(buf,sizeof(buf),"%s.%d", basename, i);
+        n.message_id = buf;
+        n.partno = i;
+        import.insert(std::pair<int,TaskUpload::Needed>(i,n));
+      }
+      g_free(basename);
+
+      foreach_const (quarks_t, groups, git)
+        a.xref.insert (profile.posting_server, *git,0);
+
+      const std::string message_id = !profile.fqdn.empty()
+      ? GNKSA::generate_message_id (profile.fqdn)
+      : GNKSA::generate_message_id_from_email_address (profile.address);
 		  TaskUpload* tmp = new TaskUpload(std::string((const char*)cur->data),
-                               profile.posting_server, _cache,
-                               groups, subject, author, a, 0, 0,
-                               TaskUpload::YENC);
+                        profile.posting_server, _cache,
+                        a, message_id, &import, 0, TaskUpload::YENC);
 		  _file_queue_tasks.push_back(tmp);
 		}
   	g_slist_free (tmp_list);
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index e85f2af..bfc4e0f 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -149,6 +149,8 @@ namespace pan
       /* binpost */
       bool _file_queue_empty;
       tasks_v _file_queue_tasks;
+      TaskUpload* _upload_ptr;
+      int _total_parts;
 
     private:
       void add_actions (GtkWidget* box);
@@ -166,8 +168,6 @@ namespace pan
       GtkWidget* create_filequeue_tab ();
       GtkWidget* create_parts_tab ();
       GtkWidget* create_log_tab ();
-      TaskUpload* _upload_ptr;
-      int _total_parts;
 
     private:
       std::string utf8ize (const StringView&) const;
diff --git a/pan/tasks/encoder.cc b/pan/tasks/encoder.cc
index 3351701..fcbe1fd 100644
--- a/pan/tasks/encoder.cc
+++ b/pan/tasks/encoder.cc
@@ -26,10 +26,12 @@
 #include <cerrno>
 #include <ostream>
 #include <fstream>
+#include <sstream>
 extern "C" {
-#  define PROTOTYPES
-#  include <uulib/uudeview.h>
-#  include <glib/gi18n.h>
+#define PROTOTYPES
+#include <uulib/uudeview.h>
+#include <glib/gi18n.h>
+#include <sys/time.h>
 };
 #include <pan/general/debug.h>
 #include <pan/general/file-util.h>
@@ -39,6 +41,39 @@ extern "C" {
 
 using namespace pan;
 
+namespace
+{
+  void generate_unique_id (StringView& mid, std::string& filename, int cnt, std::string& s)
+  {
+    std::stringstream out;
+    struct stat sb;
+    struct timeval tv;
+
+    const char * pch = mid.strchr ('@');
+    StringView domain = mid.substr (pch+1, NULL);
+    pch = domain.strchr ('>');
+    domain = domain.substr (NULL, pch);
+    domain.trim ();
+
+    // add unique local part to message-id
+    out << "pan.";
+    const time_t now (time(NULL));
+    struct tm local_now = *gmtime (&now);
+    gettimeofday (&tv, NULL);
+    char buf[64];
+    std::strftime (buf, sizeof(buf), "%Y.%m.%d.%H.%M.%S", &local_now);
+    out << buf;
+    out << "." << tv.tv_sec << "." << tv.tv_usec << "." << tv.tv_sec*tv.tv_usec;
+
+    // delimit
+    out<< '@';
+
+    // add domain
+    out << domain;
+    s = out.str();
+  }
+}
+
 Encoder :: Encoder (WorkerPool& pool):
   _worker_pool (pool),
   _gsourceid (-1)
@@ -56,13 +91,14 @@ Encoder :: ~Encoder()
 
 void
 Encoder :: enqueue (TaskUpload                      * task,
-                    const Article::mid_sequence_t   & mids,
                     EncodeCache                     * cache,
+                    Article                           article,
                     std::string                     & filename,
                     std::string                     & basename,
                     std::string                     & groups,
                     std::string                     & subject,
                     std::string                     & author,
+                    std::string                       global_mid,
                     const TaskUpload::EncodeMode    & enc)
 
 {
@@ -75,8 +111,10 @@ Encoder :: enqueue (TaskUpload                      * task,
   this->groups = groups;
   this->subject = subject;
   this->author = author;
-  this-> mids = mids;
+  this->needed = &task->_needed;
+  this->global_mid = global_mid;
   this->cache = cache;
+  this->article = article;
 
   percent = 0;
   current_file.clear ();
@@ -94,8 +132,10 @@ Encoder :: do_work()
   char buf[bufsz], buf2[bufsz];
   int cnt(1);
   crc32_t crcptr;
-
+  struct stat sb;
+  std::string s;
   FILE* outfile, * infile ;
+
   enable_progress_update();
 
     int res;
@@ -106,27 +146,43 @@ Encoder :: do_work()
       UUSetMsgCallback (this, uu_log);
       UUSetBusyCallback (this, uu_busy_poll, 200);
 
-      foreach_const(Article::mid_sequence_t, mids, it) {
+      PartBatch batch;
+      batch.init(StringView(basename), needed->size(), 0);
+      int cnt(1);
+      Article* tmp = new Article(article);
 
-        FILE * fp = cache->get_fp_from_mid(*it);
-        if (!(*it))
+      /* build real subject line */
+      g_snprintf(buf, sizeof(buf), "\"%s\" - %s (/%03d)", basename.c_str(), subject.c_str(), needed->size());
+      tmp->subject = buf;
+
+      for (TaskUpload::needed_t::iterator it = needed->begin(); it != needed->end(); ++it, ++cnt)
+      {
+        FILE * fp = cache->get_fp_from_mid(it->second.message_id);
+        if (!fp)
         {
-          g_snprintf(buf, bufsz, _("Error loading %s from cache."), it->c_str());
+          g_snprintf(buf, bufsz, _("Error loading %s from cache."), it->second.message_id.c_str());
           log_errors.push_back(buf); // log error
-          ++cnt;
           continue;
         }
-        cache->get_filename(buf, *it);
-        std::cerr<<"do work "<<buf<<std::endl;
         // 4000 lines SHOULD be OK for ANY nntp server ...
+        StringView mid(global_mid);
+        generate_unique_id(mid, filename, cnt, s);
         res = UUE_PrepPartial (fp, NULL, (char*)filename.c_str(),YENC_ENCODED,
-                               (char*)basename.c_str(),0644, cnt++, 4000,
+                               (char*)basename.c_str(),0644, cnt, 4000,
                                0, (char*)groups.c_str(),
-                               (char*)author.c_str(), (char*)subject.c_str(),
-                               0);
-        if (fp) fclose(fp);
-        std::cerr<<"encoder said : "<<UUstrerror(res)<<std::endl;
+                               (char*)author.c_str(),
+                               (char*)subject.c_str(), (char*)s.c_str(), 0);
+
         if (res != UURET_CONT) break;
+
+        cache->finalize(it->second.message_id);
+        stat (it->second.message_id.c_str(), &sb);
+        it->second.bytes  = sb.st_size;
+        task->_all_bytes += sb.st_size;
+
+        std::cerr<<"add to batch: "<<it->second.message_id<<" "<<sb.st_size<<"\n";
+
+        batch.add_part(cnt, StringView(s), sb.st_size);
       }
 
       if (res != UURET_OK)
@@ -139,6 +195,11 @@ Encoder :: do_work()
                                                        NULL, 0))
                    : UUstrerror(res));
         log_errors.push_back(buf); // log error
+      } else
+      { // prepare article for upload list
+        batch.add_part(cnt, StringView(s), sb.st_size);
+        tmp->set_parts(batch);
+        task->_upload_list.push_back(tmp);
       }
     UUCleanUp ();
     }
diff --git a/pan/tasks/encoder.h b/pan/tasks/encoder.h
index 83f3ad3..405d43e 100644
--- a/pan/tasks/encoder.h
+++ b/pan/tasks/encoder.h
@@ -60,13 +60,14 @@ namespace pan
       typedef std::vector<std::string> strings_t;
 
       void enqueue (TaskUpload                      * task,
-                    const Article::mid_sequence_t   & mids,
                     EncodeCache                     * cache,
+                    Article                           article,
                     std::string                     & filename,
                     std::string                     & basename,
                     std::string                     & groups,
                     std::string                     & subject,
                     std::string                     & author,
+                    std::string                       global_mid,
                     const TaskUpload::EncodeMode    & enc = TaskUpload::YENC);
 
     public:
@@ -86,9 +87,11 @@ namespace pan
       TaskUpload * task;
       TaskUpload::EncodeMode encode_mode;
       std::string   basename, filename;
-      std::string subject, author, groups;
+      std::string subject, author, groups, mid;
       EncodeCache * cache;
-      Article::mid_sequence_t mids;
+      TaskUpload::needed_t* needed;
+      std::string global_mid;
+      Article article;
 
       // These are set in the worker thread and polled in the main thread.
       Mutex mut;
diff --git a/pan/tasks/nzb.cc b/pan/tasks/nzb.cc
index 0a897fe..7cafa04 100644
--- a/pan/tasks/nzb.cc
+++ b/pan/tasks/nzb.cc
@@ -57,6 +57,7 @@ namespace
     ArticleRead& read;
     const ServerRank& ranks;
     const GroupServer& gs;
+    Quark server;
     const StringView fallback_path;
     size_t bytes;
     size_t number;
@@ -101,6 +102,7 @@ namespace
       for (const char **k(attribute_names), **v(attribute_vals); *k; ++k, ++v) {
              if (!strcmp (*k,"author"))  mc.a.author = *v;
         else if (!strcmp (*k,"subject")) mc.a.subject = *v;
+        else if (!strcmp (*k,"server"))  mc.server = *v;
       }
     }
 
@@ -147,18 +149,16 @@ namespace
     }
 
     else if (!strcmp(element_name, "part") && mc.number && !mc.text.empty()) {
-//      TaskUpload::Needed n;
-//      n.bytes = mc.bytes;
-//      n.filename = mc.text;
-//      n.partno = mc.number;
-//      n.partial = false;
-//      std::pair<int,TaskUpload::Needed> tmp(mc.number,n);
-//      mc.needed_parts.insert(tmp);
-      if (mc.a.message_id.empty()) {
-        mc.a.message_id = mc.text;
-        mc.parts.init (mc.text);
-      }
-      mc.parts.add_part (mc.number, mc.text, mc.bytes);
+//      if (mc.a.message_id.empty()) {
+//        mc.a.message_id = mc.text;
+//        mc.parts.init (mc.text);
+//      }
+      mc.a.message_id = mc.text;
+      TaskUpload::Needed n;
+      n.partno = mc.number;
+      n.message_id = mc.text;
+      n.bytes = mc.bytes;
+      mc.needed_parts.insert(std::pair<int, TaskUpload::Needed>(mc.number,n));
     }
 
     else if (!strcmp(element_name,"path"))
@@ -183,16 +183,13 @@ namespace
     else if (!strcmp (element_name, "upload"))
     {
       debug("adding taskupload from nzb.\n");
-//      TaskUpload::needed_t tmp2;
-//      foreach (TaskUpload::needed_t, mc.needed_parts, it)
-//        tmp2.insert(*it);
-      mc.parts.sort ();
-      mc.a.set_parts (mc.parts);
-      foreach_const (quarks_t, mc.groups, git)
-        mc.a.xref.insert (Quark("dummy"), *git,0);
+//      mc.parts.sort ();
+//      mc.a.set_parts (mc.parts);
+//      foreach_const (quarks_t, mc.groups, git)
+//        mc.a.xref.insert (mc.server, *git,0);
 
-      TaskUpload* tmp = new TaskUpload (mc.path, Quark("dummy"), mc.encode_cache,
-                          mc.groups, mc.a.subject.to_string(), mc.a.author.to_string(), mc.a, 0, 0, TaskUpload::YENC);
+      TaskUpload* tmp = new TaskUpload (mc.path, mc.server, mc.encode_cache,
+                          mc.a, mc.a.message_id.to_string() , &mc.needed_parts, 0, TaskUpload::YENC);
       mc.tasks.push_back (tmp);
     }
   }
@@ -350,7 +347,7 @@ NZB :: nzb_to_xml (std::ostream             & out,
       // not an upload task, move on
       if (!task) continue;
 
-      std::vector<std::string> groups;
+      const Article& a (task->get_article());
 
       //info: author, subject, load path, parts to encode / post
       out << indent(depth)
@@ -364,28 +361,88 @@ NZB :: nzb_to_xml (std::ostream             & out,
       out << indent(depth)
           << "<path>" << task->_filename << "</path>\n";
       out  << indent(depth) << "<groups>\n";
+
       ++depth;
-      foreach_const (quarks_t, task->_groups, it)
-      {
-        out << indent(depth)<<"<group>" << (*it).to_string() << "</group>\n";
-      }
+      foreach_const (quarks_t, task->_groups, git)
+        out << indent(depth) << "<group>" << *git << "</group>\n";
       --depth;
-      out  << indent(depth) << "</groups>\n";
+
+      out << indent(--depth) << "</groups>\n";
       out  << indent(depth) << "<parts>\n";
       ++depth;
 
-      foreach_const (TaskUpload::needed_t, task->_needed, it)
+      foreach (TaskUpload::needed_t, task->_needed, it)
+      {
         out << indent(depth)
-            << "<part" << " bytes=\"" << (*it).second.bytes << '"'
-                       << " number=\"" << (*it).second.partno << '"'
-                       << ">" << (*it).second.filename<< "</part>\n";
+            << "<part" << " bytes=\"" << it->second.bytes << '"'
+                          << " number=\"" << it->second.partno << '"'
+                          << ">";
+        escaped(out, it->second.message_id);
+        out  << "</part>\n";
+      }
       --depth;
       out  << indent(depth) << "</parts>\n";
-      --depth;
       out << indent(depth) << "</upload>\n";
+    }
+  }
+  out << indent(--depth) << "</nzb>\n";
+  return out;
+}
+
+/* Saves upload_list to XML file for distribution */
+std::ostream&
+NZB :: upload_list_to_xml_file (std::ostream& out,
+                   const std::vector<Article*> & tasks)
+{
+int depth (0);
+
+  out << "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+      << "<!DOCTYPE nzb PUBLIC \"-//newzBin//DTD NZB 1.0//EN\" \"http://www.newzbin.com/DTD/nzb/nzb-1.0.dtd\";>\n"
+      << indent(depth++)
+      << "<nzb xmlns=\"http://www.newzbin.com/DTD/2003/nzb\";>\n";
 
+  foreach_const (std::vector<Article*>, tasks, it)
+  {
+    Article * task (dynamic_cast<Article*>(*it));
+    const Article& a (*task);
 
+    out << indent(depth++)
+        << "<file" << " poster=\"";
+    escaped (out, a.author.to_view());
+    out  << "\" date=\"" << a.time_posted << "\" subject=\"";
+    escaped (out, a.subject.to_view()) << "\">\n";
+
+    // what groups was this crossposted in?
+    quarks_t groups;
+    foreach_const (Xref, a.xref, xit)
+      groups.insert (xit->group);
+    out << indent(depth++) << "<groups>\n";
+    foreach_const (quarks_t, groups, git)
+      out << indent(depth) << "<group>" << *git << "</group>\n";
+    out << indent(--depth) << "</groups>\n";
+
+    // now for the parts...
+    out << indent(depth++) << "<segments>\n";
+    for (Article::part_iterator it(a.pbegin()), end(a.pend()); it!=end; ++it)
+    {
+      std::string mid = it.mid ();
+
+      // remove the surrounding < > as per nzb spec
+      if (mid.size()>=2 && mid[0]=='<') {
+        mid.erase (0, 1);
+        mid.resize (mid.size()-1);
+      }
+
+      // serialize this part
+      out << indent(depth)
+          << "<segment" << " bytes=\"" << it.bytes() << '"'
+                        << " number=\"" << it.number() << '"'
+                        << ">";
+      escaped(out, mid);
+      out  << "</segment>\n";
     }
+    out << indent(--depth) << "</segments>\n";
+    out << indent(--depth) << "</file>\n";
   }
 
   out << indent(--depth) << "</nzb>\n";
diff --git a/pan/tasks/nzb.h b/pan/tasks/nzb.h
index d8b4152..2314768 100644
--- a/pan/tasks/nzb.h
+++ b/pan/tasks/nzb.h
@@ -56,6 +56,8 @@ namespace pan
     static std::ostream&  nzb_to_xml (std::ostream             & out,
                                       const std::vector<Task*> & tasks);
 
+    static std::ostream&  upload_list_to_xml_file (std::ostream& out,
+                                                   const std::vector<Article*> & tasks);
 
     static std::ostream&  nzb_to_xml_file (std::ostream             & out,
                                            const std::vector<Task*> & tasks);
diff --git a/pan/tasks/task-upload.cc b/pan/tasks/task-upload.cc
index f1fe16f..31b6487 100644
--- a/pan/tasks/task-upload.cc
+++ b/pan/tasks/task-upload.cc
@@ -39,28 +39,31 @@ extern "C" {
 #include <pan/data/encode-cache.h>
 #include "encoder.h"
 #include "task-upload.h"
+#include "nzb.h"
 
 using namespace pan;
 
+///TODO refresh actual filesize inside article parts! (by encoder)
+
 namespace
 {
   std::string get_description (const char* name)
   {
-    char buf[1024];
+    char buf[4096];
     char * freeme = g_path_get_basename(name);
     snprintf (buf, sizeof(buf), _("Uploading %s"), freeme);
     g_free(freeme);
     return buf;
   }
 
-//  std::string get_basename(const char* f)
-//  {
-//    char buf[4096];
-//    char * freeme = g_path_get_basename(f);
-//    snprintf (buf, sizeof(buf), _("%s"), freeme);
-//    g_free(freeme);
-//    return buf;
-//  }
+  std::string get_basename(const char* f)
+  {
+    char buf[4096];
+    char * freeme = g_path_get_basename(f);
+    snprintf (buf, sizeof(buf), _("%s"), freeme);
+    g_free(freeme);
+    return buf;
+  }
 }
 
 
@@ -71,25 +74,25 @@ namespace
 TaskUpload :: TaskUpload (const std::string         & filename,
                           const Quark               & server,
                           EncodeCache               & cache,
-                          quarks_t                  & groups,
-                          std::string                 subject,
-                          std::string                 author,
-                          Article                   & article,
+                          Article                     article,
+                          std::string                 mid,
                           needed_t                  * imported,
                           Progress::Listener        * listener,
                           const TaskUpload::EncodeMode  enc):
   Task ("UPLOAD", get_description(filename.c_str())),
   _filename(filename),
-  _basename (g_path_get_basename(filename.c_str())),
+  _basename (get_basename(filename.c_str())),
   _server(server),
   _cache(cache),
-  _groups(groups),
-  _subject (subject),
-  _author(author),
+  _article(article),
+  _subject (article.subject.to_string()),
+  _author(article.author.to_string()),
   _encoder(0),
   _encoder_has_run (false),
   _encode_mode(enc),
-  _lines_per_file(4000)
+  _mid(mid),
+  _lines_per_file(4000),
+  _all_bytes(0)
 {
   if (listener != 0)
     add_listener (listener);
@@ -102,9 +105,8 @@ TaskUpload :: TaskUpload (const std::string         & filename,
   struct stat sb;
   stat(filename.c_str(),&sb);
   _bytes = sb.st_size;
-
   build_needed_tasks(imported);
-  _cache.reserve(_article.get_part_mids());
+
   update_work ();
 }
 
@@ -112,46 +114,26 @@ void
 TaskUpload :: build_needed_tasks(bool imported)
 {
 
-  char buf[4096];
-  char buf2[4096];
-
   _total_parts = (int) (((long)get_byte_count() + (4000*128-1)) / (4000*128));
   int cnt(1);
 
   quarks_t groups;
   foreach_const (Xref, _article.xref, it)
-    groups.insert (it->group);
-
-  for (int i=1; i<=_total_parts; ++i)
+    _groups.insert (it->group);
+
+//  TaskUpload::Needed n;
+//  foreach_const (quarks_t, groups, git)
+//      n.xref.insert (_server, *git, StringView(buf)==_article.message_id.to_string()
+//                     ? _article.xref.find_number(_server,*git) : 0);
+  Article::mid_sequence_t mids;
+  foreach (needed_t, _needed, it)
   {
-    if (imported)
-    {
-    needed_t::iterator it = _needed.find(cnt);
-    if (it == _needed.end())
-      continue;
-    }
-
-    g_snprintf(buf,sizeof(buf),"%s.%d", _filename.c_str(), i);
-    _article.add_part(i, StringView(buf), 0);
+    mids.push_back(Quark(it->second.message_id));
+    _cache.add(Quark(it->second.message_id));
   }
+  _cache.reserve(mids);
+  _needed_parts = _needed.size();
 
-  for (Article::part_iterator i(_article.pbegin()), e(_article.pend()); i!=e; ++i, ++cnt)
-  {
-    const std::string mid (i.mid ());
-
-    TaskUpload::Needed n;
-    n.message_id = mid;
-    n.bytes = i.bytes();
-    n.partno = cnt;
-
-    foreach_const (quarks_t, groups, git)
-      n.xref.insert (_server, *git, mid==_article.message_id.to_string()
-                     ? _article.xref.find_number(_server,*git) : 0);
-
-    std::cerr<<"needed insert "<<cnt<<std::endl;
-    _needed.insert(std::pair<int,Needed>(cnt,n));
-  }
-  _needed_parts = cnt;
 }
 
 void
@@ -179,7 +161,6 @@ TaskUpload :: update_work (NNTP* checkin_pending)
   {
     _state.set_completed();
     set_finished(OK);
-
   }
 }
 
@@ -201,7 +182,6 @@ TaskUpload :: use_nntp (NNTP * nntp)
       }
   }
 
-
   if (!needed)
   {
     update_work (nntp);
@@ -237,6 +217,7 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
 
   char buf[4096];
   Log::Entry tmp;
+  tmp.date = time(NULL);
 
   needed_t::iterator it;
   for (it=_needed.begin(); it!=_needed.end(); ++it)
@@ -248,13 +229,12 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
   {
     case OK:
       // save to cache
+      increment_step(it->second.bytes);
       _needed.erase (it);
       post_ok = true;
-      increment_step(1);
       break;
     case ERR_NETWORK:
-      //reset
-      it->second.nntp = 0;
+      it->second.reset();
       goto _end;
     case ERR_COMMAND:
       _needed.erase (it);
@@ -269,8 +249,10 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
       this->stop();
       break;
     case POSTING_FAILED:
-      Log :: add_err_va ( _("Posting of File %s (Part %d of %d) failed: %s"),
+      g_snprintf(buf,sizeof(buf), _("Posting of File %s (Part %d of %d) failed: %s"),
                  _basename.c_str(), it->second.partno, _total_parts, response.str);
+      tmp.message = buf;
+      _logfile.push_back(tmp);
       break;
     case ARTICLE_POSTED_OK:
       tmp.severity = Log :: PAN_SEVERITY_INFO;
@@ -280,7 +262,6 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
                    _basename.c_str(), it->second.partno, _total_parts, response.str);
         tmp.message = buf;
         _logfile.push_back(tmp);
-        std::cerr<<LINE_ID<<" "<<_logfile.size()<<std::endl;
       } else if (post_ok && _needed.empty())
       {
         g_snprintf(buf,sizeof(buf), _("Posting of file %s (Part %d of %d) succesful: %s"),
@@ -292,12 +273,13 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
         tmp.message = buf;
         _logfile.push_back(tmp);
         Log::add_entry_list (tmp, _logfile);
-        std::cerr<<LINE_ID<<" "<<_logfile.size()<<std::endl;
+        _logfile.clear();
       } else
       {
+        Log::add_entry_list (tmp, _logfile);
+        _logfile.clear();
         Log :: add_err_va (_("Posting of file %s not successful: Check the popup log!"),
                    _basename.c_str(), response.str);
-        std::cerr<<LINE_ID<<" "<<_logfile.size()<<std::endl;
       }
       break;
     case TOO_MANY_CONNECTIONS:
@@ -344,11 +326,8 @@ TaskUpload :: use_encoder (Encoder* encoder)
     if (i<_groups.size()&& i>0 && _groups.size()>1) groups += ",";
     groups += (*it).to_string();
   }
-  const Article::mid_sequence_t mids (_article.get_part_mids());
-  foreach_const (Article::mid_sequence_t, mids, it)
-    _cache.add(*it) ? std::cerr<<"fp valid!\n" :std::cerr<<"fp invalid!\n";
-  _encoder->enqueue (this, mids, &_cache, _filename, _basename,
-                     groups, _subject, _author, YENC);
+  _encoder->enqueue (this, &_cache, _article, _filename, _basename,
+                     groups, _subject, _author, _mid, YENC);
   debug ("encoder thread was free, enqueued work");
 }
 
@@ -382,9 +361,8 @@ TaskUpload :: on_worker_done (bool cancelled)
       set_error (_encoder->log_errors.front());
 
     {
-      std::cerr<<_encoder->parts<<" "<<_total_parts<<std::endl;
       set_step (0);
-      init_steps(_needed_parts);
+      init_steps(_all_bytes);
       _encoder_has_run = true;
     }
   }
@@ -395,9 +373,24 @@ TaskUpload :: on_worker_done (bool cancelled)
   check_in (d);
 }
 
+namespace
+{
+  void add_to_upload_list(std::vector<Article*>& vec)
+  {
+    std::ofstream out("/home/imhotep/download_list", std::fstream::out | std::fstream::app);
+    NZB :: upload_list_to_xml_file (out, vec);
+    out.close();
+  }
+}
+
 TaskUpload :: ~TaskUpload ()
 {
   // ensure our on_worker_done() doesn't get called after we're dead
   if (_encoder)
       _encoder->cancel_silently();
+
+  _cache.release(_article.get_part_mids());
+  _cache.resize();
+
+  add_to_upload_list(_upload_list);
 }
diff --git a/pan/tasks/task-upload.h b/pan/tasks/task-upload.h
index df81964..0106d2d 100644
--- a/pan/tasks/task-upload.h
+++ b/pan/tasks/task-upload.h
@@ -49,20 +49,20 @@ namespace pan
   {
     public:
 
+      ///TODO SEE!
       void set_lpf (const int& setme ) { _lines_per_file = setme; }
+      const Article& get_article ()  { return _article; }
 
       typedef std::vector<Quark> mid_sequence_t;
 
       struct Needed {
-        std::string filename;
         unsigned long bytes;
         int partno;
         NNTP* nntp;
-        bool partial;
         std::string message_id;
         Xref xref;
-
-        Needed (): nntp(0), bytes(0) , partial(false) {}
+        bool encoded;
+        Needed (): nntp(0), bytes(0) , partno(1), encoded(false) {}
         void reset() { nntp = 0; }
       };
 
@@ -79,10 +79,8 @@ namespace pan
       TaskUpload ( const std::string         & filename,
                    const Quark               & server,
                    EncodeCache               & cache,
-                   quarks_t                  & groups,
-                   std::string                 subject,
-                   std::string                 author,
-                   Article                   & article,
+                   Article                     article,
+                   std::string                 mid,
                    needed_t                  * imported=0,
                    Progress::Listener        * listener= 0,
                    TaskUpload::EncodeMode enc= YENC);
@@ -137,6 +135,9 @@ namespace pan
       EncodeCache& _cache;
       std::deque<Log::Entry> _logfile;   // for intermediate updates
       Article _article;
+      std::string _mid;
+      unsigned long _all_bytes;
+      std::vector<Article*> _upload_list;
 
     private:
       needed_t       _needed;
diff --git a/uulib/uudeview.h b/uulib/uudeview.h
index 5422bf2..8df7e9d 100644
--- a/uulib/uudeview.h
+++ b/uulib/uudeview.h
@@ -242,8 +242,8 @@ int	UUEXPORT UUE_PrepSingle		_ANSI_ARGS_((FILE *, FILE *,
 int	UUEXPORT UUE_PrepPartial	_ANSI_ARGS_((FILE *, FILE *,
 						     char *, int,
 						     char *, int,
-						     int, long, long, char *,
-						     char *, char *, int));
+						     int, long, long,
+						     char *, char *, char*, char*, int));
 
 int	UUEXPORT UUE_PrepSingleExt	_ANSI_ARGS_((FILE *, FILE *,
 						     char *, int,
@@ -254,7 +254,7 @@ int	UUEXPORT UUE_PrepSingleExt	_ANSI_ARGS_((FILE *, FILE *,
 int	UUEXPORT UUE_PrepPartialExt	_ANSI_ARGS_((FILE *, FILE *,
 						     char *, int,
 						     char *, int,
-						     int, long, long, char *,
+						     int, long, long, char *, char*,
 						     char *, char *, char *,
 						     int));
 #ifdef __cplusplus
diff --git a/uulib/uuencode.c b/uulib/uuencode.c
index c24acbb..c02eba3 100644
--- a/uulib/uuencode.c
+++ b/uulib/uuencode.c
@@ -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);
     }
 
@@ -1522,6 +1522,8 @@ UUE_PrepSingleExt (FILE *outfile, FILE *infile,
     return UURET_ILLVAL;
   }
 
+  if (!outfile) return UURET_IOERR;
+
   oname = UUFNameFilter ((outfname)?outfname:infname);
   len   = ((subject)?strlen(subject):0) + strlen(oname) + 40;
 
@@ -1545,9 +1547,9 @@ UUE_PrepSingleExt (FILE *outfile, FILE *infile,
 
   if (encoding == YENC_ENCODED) {
     if (subject)
-      sprintf (subline, "%s \"%s\"", subject, oname);
+      sprintf (subline, "- %s - %s (001/001)", oname, subject);
     else
-      sprintf (subline, "%s ", oname);
+      sprintf (subline, "- %s - (001/001)", oname);
   }
   else {
     if (subject)
@@ -1585,7 +1587,7 @@ UUE_PrepSingleExt (FILE *outfile, FILE *infile,
 
   res = UUEncodeToStream (outfile, infile, infname, encoding,
 			  outfname, filemode);
-  
+
   _FP_free (subline);
   return res;
 }
@@ -1595,7 +1597,7 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
 		 char *infname, int encoding,
 		 char *outfname, int filemode,
 		 int partno, long linperfile, long filesize,
-		 char *destination, char *from, char *subject,
+		 char *destination, char *from, char *subject, char* mid,
 		 int isemail)
 {
   return UUE_PrepPartialExt (outfile, infile,
@@ -1603,7 +1605,7 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
 			     outfname, filemode,
 			     partno, linperfile, filesize,
 			     destination,
-			     from, subject, NULL,
+			     from, subject, mid, NULL,
 			     isemail);
 }
 
@@ -1613,7 +1615,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
 		    char *outfname, int filemode,
 		    int partno, long linperfile, long filesize,
 		    char *destination,
-		    char *from, char *subject, char *replyto,
+		    char *from, char *subject, char* mid, char *replyto,
 		    int isemail)
 {
   static int numparts, themode;
@@ -1634,6 +1636,8 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
     return UURET_ILLVAL;
   }
 
+  if (!outfile) return UURET_IOERR;
+
   oname = UUFNameFilter ((outfname)?outfname:infname);
   len   = ((subject)?strlen(subject):0) + strlen (oname) + 40;
 
@@ -1657,7 +1661,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]));
 
@@ -1725,24 +1729,23 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
   }
 
 
-  /* 1.3 draft: [Comment1] "filename" yEnc (partnum/numparts) [size] [Comment2] */
   if (encoding == YENC_ENCODED) {
     if (partno == 1)
       crc = crc32(0L, Z_NULL, 0);
     crcptr = &crc;
     if (subject)
-      sprintf (subline, "%s \"%s\" (%d/%d)", subject, oname,
+      sprintf (subline, "\"%s\" - %s (%03d/%03d)", oname, subject,
 	       partno, numparts);
     else
-      sprintf (subline, "%s (%d/%d)", oname,
+      sprintf (subline, "\"%s\" - (%03d/%03d)", oname,
 	       partno, numparts);
   }
   else {
     if (subject)
-      sprintf (subline, "%s (%d/%d) - [ %s ]",
+      sprintf (subline, "%s (%03d/%03d) - [ %s ]",
 	       subject, partno, numparts, oname);
     else
-      sprintf (subline, "[ %s ] (%d/%d)",
+      sprintf (subline, "[ %s ] (%03d/%03d)",
 	       oname, partno, numparts);
   }
 
@@ -1758,6 +1761,11 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
 
   fprintf (outfile, "Subject: %s%s", subline, eolstring);
 
+//  if (mid)
+//  {
+//    fprintf(outfile, "Message-ID: <%s>%s", mid, eolstring);
+//  }
+
   if (replyto) {
     fprintf (outfile, "Reply-To: %s%s", replyto, eolstring);
   }
@@ -1769,7 +1777,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]