Changeset 1a970cd0640f976f152341597a5249ec22acbba7
- Timestamp:
- 09/05/10 21:25:41 (21 months ago)
- Children:
- c53e53f1cb0d542e5c931555a591d2589c033006
- Parents:
- e7bbf3c6b857df8ad33c4d39396d693b48a48461
- git-committer:
- Antti-Juhani Kaijanaho <antti-juhani@…> (09/05/10 21:25:41)
- Files:
-
- 1 added
- 1 removed
- 28 modified
- 1 moved
-
db/db.cc (modified) (7 diffs)
-
db/db.hh (modified) (5 diffs)
-
db/group.cc (modified) (2 diffs)
-
db/group.hh (modified) (4 diffs)
-
db/msg.cc (added)
-
db/msg.hh (moved) (moved from msg/msg.hh) (3 diffs)
-
db/threaded.cc (modified) (2 diffs)
-
db/threaded.hh (modified) (5 diffs)
-
db/user.cc (modified) (1 diff)
-
http/article.cc (modified) (2 diffs)
-
http/article_entry.cc (modified) (5 diffs)
-
http/compose.cc (modified) (10 diffs)
-
http/compose.hh (modified) (3 diffs)
-
http/group_feed.cc (modified) (3 diffs)
-
http/thread_feed.cc (modified) (4 diffs)
-
local/connection.cc (modified) (2 diffs)
-
msg/entity.cc (modified) (5 diffs)
-
msg/entity.hh (modified) (4 diffs)
-
msg/message_entity.cc (modified) (1 diff)
-
msg/msg.cc (deleted)
-
msg/util.cc (modified) (3 diffs)
-
msg/util.hh (modified) (2 diffs)
-
nntp/article.cc (modified) (4 diffs)
-
nntp/hdr.cc (modified) (6 diffs)
-
nntp/last.cc (modified) (2 diffs)
-
nntp/next.cc (modified) (2 diffs)
-
nntp/over.cc (modified) (6 diffs)
-
nntp/post.cc (modified) (2 diffs)
-
smtp_client/smtp_client.cc (modified) (2 diffs)
-
tlate/date_value.cc (modified) (1 diff)
-
tlate/msg_value.cc (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
db/db.cc
r7ccc366 r1a970cd 20 20 #include "db.hh" 21 21 #include "db_reader.hh" 22 #include "msg.hh" 22 23 #include "role.hh" 23 24 #include "role_exists.hh" … … 27 28 #include "../config.hh" 28 29 #include "../logger/logline.hh" 29 #include "../msg/msg.hh" 30 #include "../msg/entity.hh" 31 #include "../msg/util.hh" 30 32 #include "../myassert.hh" 31 33 #include "../util.hh" … … 220 222 221 223 std::string msgstr = 222 msg::dot_destuff(msg::crlf_canonize(ss.str()));224 ::msg::dot_destuff(::msg::crlf_canonize(ss.str())); 223 225 224 226 // commit 225 boost::shared_ptr<msg::msg> message(new msg::msg(msgid,msgstr)); 227 ::msg::entity::ptr entity(new ::msg::entity(msgstr)); 228 msg::ptr message(new msg::msg(msgid,entity)); 226 229 for (std::map<std::string, group::number>::const_iterator it = 227 230 xref.begin(); … … 309 312 } 310 313 311 void db::file(boost::shared_ptr<msg::msg> mg,312 boost::asio::ip::address source,313 boost::shared_ptr<user> poster,314 server::conn_cb cb)314 boost::shared_ptr<msg> db::file(boost::shared_ptr< ::msg::entity > ent, 315 boost::asio::ip::address source, 316 boost::shared_ptr<user> poster, 317 server::conn_cb cb) 315 318 { 316 319 // first, perform USEPRO-14 (USEFOR-12) injector duties 317 320 318 mg->complete_netnews();321 ::msg::complete_netnews(ent); 319 322 320 323 std::string server_name = … … 330 333 << source.to_string() 331 334 << "\""; 332 mg->replace_field("Injection-Info", ss.str());333 } 334 335 std::string path = mg->get_field("Path", false);335 ent->replace_field("Injection-Info", ss.str()); 336 } 337 338 std::string path = ent->get_field("Path", false); 336 339 util::strip_crlf(path); 337 340 if (path.empty()) … … 349 352 path = server_name + 350 353 " !.POSTED." + source.to_string() + " !" + path; 351 mg->replace_field("Path", path); 352 353 mg->validate_netnews(); 354 ent->replace_field("Path", path); 355 356 ::msg::validate_netnews(ent); 357 358 msg::ptr mg(new msg(ent)); 354 359 355 360 boost::lock_guard<boost::recursive_mutex> lg(mt); … … 432 437 } 433 438 dbfile << "FOLLOWS\n" 434 << msg::dot_stuff(mg->get_entity())439 << ::msg::dot_stuff(mg->get_entity()->get_entity()) 435 440 << ".END\n"; 436 441 dbfile.close(); 442 return mg; 437 443 } 438 444 -
db/db.hh
r7ccc366 r1a970cd 35 35 #include <fstream> 36 36 37 namespace msg { class msg; }37 namespace msg { class entity; } 38 38 39 39 namespace db 40 40 { 41 class msg; 41 42 class user; 42 43 class password_handler; … … 52 53 typedef std::map<std::string,boost::shared_ptr<group> > 53 54 ::const_iterator group_iterator; 54 typedef std::map<std::string,boost::shared_ptr<msg ::msg> >55 typedef std::map<std::string,boost::shared_ptr<msg> > 55 56 ::const_iterator msgid_iterator; 56 57 … … 67 68 msgid_iterator msgids_end() const { return msgid.end(); } 68 69 69 boost::shared_ptr<msg ::msg> lookup_msgid(std::string s) {70 boost::shared_ptr<msg> lookup_msgid(std::string s) { 70 71 boost::lock_guard<boost::recursive_mutex> lg(mt); 71 72 msgid_iterator it = msgid.find(s); … … 81 82 } 82 83 83 void file(boost::shared_ptr<msg::msg> mg,84 boost::asio::ip::address source,85 boost::shared_ptr<user> poster,86 server::conn_cb);84 boost::shared_ptr<msg> file(boost::shared_ptr< ::msg::entity >, 85 boost::asio::ip::address source, 86 boost::shared_ptr<user> poster, 87 server::conn_cb); 87 88 88 89 const threaded &get_threaded() { … … 120 121 std::map<std::string, boost::shared_ptr<role> > roles; 121 122 std::map<std::string, boost::shared_ptr<group> > groups; 122 std::map<std::string, boost::shared_ptr<msg ::msg> > msgid;123 std::map<std::string, boost::shared_ptr<msg> > msgid; 123 124 124 125 std::string dbname; -
db/group.cc
re044cc7 r1a970cd 24 24 25 25 #include "../config.hh" 26 #include "../msg/ msg.hh"26 #include "../msg/entity.hh" 27 27 #include "../smtp_client/smtp_client.hh" 28 28 … … 69 69 if (recv.empty()) return rv; 70 70 71 msg::msg::ptr nm(new msg::msg(*m));71 ::msg::entity::ptr nm(new ::msg::entity(*m->get_entity())); 72 72 { 73 73 std::string subject = nm->get_field("subject", false); -
db/group.hh
r4c34ee2 r1a970cd 34 34 #include <vector> 35 35 36 namespace msg { class msg; }37 38 36 namespace db 39 37 { 40 38 class db; 39 class msg; 41 40 class role; 42 41 class threaded_group; … … 72 71 bool is_article(number n) const { return retrieve(n); } 73 72 74 boost::shared_ptr<msg ::msg> get_article(number n) const {75 boost::shared_ptr<msg ::msg> rv = retrieve(n);73 boost::shared_ptr<msg> get_article(number n) const { 74 boost::shared_ptr<msg> rv = retrieve(n); 76 75 if (!rv) throw no_such_article(); 77 76 return rv; 78 77 } 79 78 80 number file(boost::shared_ptr<msg ::msg> m, server::conn_cb);79 number file(boost::shared_ptr<msg> m, server::conn_cb); 81 80 82 void file(boost::shared_ptr<msg ::msg> m, number n);81 void file(boost::shared_ptr<msg> m, number n); 83 82 84 83 number get_count() const { return count; } … … 114 113 115 114 size_t displacement; 116 std::vector<boost::shared_ptr<msg ::msg> > msgs;115 std::vector<boost::shared_ptr<msg> > msgs; 117 116 118 117 std::set<boost::shared_ptr<role> > readers; … … 122 121 const std::set<boost::shared_ptr<role> > &); 123 122 124 boost::shared_ptr<msg ::msg> retrieve(number n) const {125 static boost::shared_ptr<msg ::msg> null;123 boost::shared_ptr<msg> retrieve(number n) const { 124 static boost::shared_ptr<msg> null; 126 125 if (n < displacement) return null; 127 126 if (n - displacement >= msgs.size()) return null; -
db/msg.hh
r4c1c17d r1a970cd 21 21 #define GUARD_MSG_MSG_HH 22 22 23 #include "entity.hh"24 25 23 #include "../db/article_number_type.hh" 26 24 #include "../util.hh" … … 28 26 #include <boost/shared_ptr.hpp> 29 27 #include <boost/tuple/tuple.hpp> 30 #include <boost/date_time/posix_time/posix_time.hpp> 28 #include <list> 29 #include <map> 31 30 32 namespace db { class group; class user; class thread_node; }31 namespace msg { class entity; } 33 32 34 namespace msg33 namespace db 35 34 { 36 std::string crlf_canonize(std::string);37 std::string dot_stuff(std::string);38 std::string dot_destuff(std::string);39 boost::posix_time::ptime parse_date(std::string date);40 35 41 class msg : public entity 36 class group; class user; class thread_node; 37 38 class msg 42 39 { 43 40 public: … … 45 42 typedef boost::shared_ptr<const msg> const_ptr; 46 43 47 typedef std::map<boost::shared_ptr< db::group>,48 db::article_number_type>44 typedef std::map<boost::shared_ptr<group>, 45 article_number_type> 49 46 xref_type; 50 47 51 msg(std::string msgid, std::string msgstr); 52 msg(std::string msgstr); 48 explicit msg(std::string msgid, 49 boost::shared_ptr< ::msg::entity >); 50 explicit msg(boost::shared_ptr< ::msg::entity >); 53 51 54 void complete_mime(); 55 void complete_netnews(); 56 void complete_imf(); 57 void validate_netnews(); 58 void validate_imf(); 59 60 boost::posix_time::ptime parsed_date() const { 61 return the_date; 62 } 52 boost::shared_ptr<const ::msg::entity> get_entity() const 53 { return actual; } 63 54 64 55 std::list<std::string> get_newsgroups() const; 65 56 66 void replace_field(std::string name, std::string body);67 68 57 const xref_type &get_xref() const 69 { return the_xref; } 58 { return the_xref; } 70 59 71 60 std::string get_xref_field(bool full) const; 72 61 73 62 std::string msgid() const { return the_msgid; } 74 void set_msgid();75 63 76 void xref(boost::shared_ptr< db::group> gr,77 db::article_number_type n)64 void xref(boost::shared_ptr<group> gr, 65 article_number_type n) 78 66 { the_xref[gr] = n; } 79 67 80 bool reading_authz(boost::shared_ptr<const db::user> u) const;81 bool posting_authz(boost::shared_ptr<const db::user> u) const;68 bool reading_authz(boost::shared_ptr<const user> u) const; 69 bool posting_authz(boost::shared_ptr<const user> u) const; 82 70 private: 83 71 std::string the_msgid; 84 boost::posix_time::ptime the_date;85 72 xref_type the_xref; 86 87 void check_present(std::string hdr); 88 void check_absent(std::string hdr); 73 boost::shared_ptr< ::msg::entity > actual; 89 74 }; 90 75 -
db/threaded.cc
re1af652 r1a970cd 20 20 #include "threaded.hh" 21 21 22 #include "../msg/entity.hh" 22 23 #include "../msg/lexutils.hh" 23 #include "../msg/msg.hh"24 24 #include "../html/util.hh" 25 25 #include "../tlate/sequential_value.hh" … … 159 159 grinx = grinx_; 160 160 art = art_; 161 my_date = art-> parsed_date();161 my_date = art->get_entity()->parsed_date(); 162 162 if (latest_date < my_date) 163 163 latest_date = my_date; 164 std::string refss = art->get_field("references", false); 164 std::string refss = 165 art->get_entity()->get_field("references", false); 165 166 ptr prev; 166 167 while (!refss.empty()) 167 168 { 168 std::string ref = msg::get_msgid(refss);169 std::string ref = ::msg::get_msgid(refss); 169 170 if (ref.empty()) continue; 170 171 ptr &tn = msgids[ref]; -
db/threaded.hh
r299b297 r1a970cd 22 22 23 23 #include "group.hh" 24 #include "msg.hh" 24 25 25 #include "../msg/msg.hh"26 26 #include "../tlate/tlate.hh" 27 27 … … 42 42 std::string msgid; 43 43 group::number grinx; 44 boost::shared_ptr<msg ::msg> art;44 boost::shared_ptr<msg> art; 45 45 boost::posix_time::ptime my_date, latest_date; 46 46 std::list<ptr> children; … … 77 77 78 78 void add_msg(group::number grinx, 79 boost::shared_ptr<msg ::msg> art);79 boost::shared_ptr<msg> art); 80 80 void prune(); 81 81 bool has_descendant(ptr); … … 90 90 } 91 91 const std::list<ptr> &get_children() const { return children; } 92 boost::shared_ptr<msg ::msg> get_article() const { return art; }92 boost::shared_ptr<msg> get_article() const { return art; } 93 93 template <typename Cmp> 94 94 void sort_children(Cmp cmp) { … … 146 146 147 147 void add_msg(group::number grinx, 148 boost::shared_ptr<msg ::msg> art);148 boost::shared_ptr<msg> art); 149 149 const std::list<thread_node::ptr> &get_threads() const 150 150 { return root->get_children(); } -
db/user.cc
r92c18c1 r1a970cd 151 151 mam->insert("from", from); 152 152 mam->insert("to", 153 msg::make_phrase(ton) + " <" + to + ">");153 ::msg::make_phrase(ton) + " <" + to + ">"); 154 154 mam->insert("userid", userid); 155 155 mam->insert("link", link.str()); -
http/article.cc
r654bb60 r1a970cd 25 25 26 26 #include "../db/db.hh" 27 #include "../db/msg.hh" 27 28 #include "../db/threaded.hh" 28 29 #include "../html/util.hh" 29 30 #include "../msg/content_type.hh" 30 31 #include "../msg/lexutils.hh" 31 #include "../msg/msg.hh"32 32 #include "../msg/text_plain.hh" 33 33 #include "../server.hh" … … 56 56 tlate::data_model::ptr am) 57 57 { 58 boost::shared_ptr< msg::msg> art;58 boost::shared_ptr<db::msg> art; 59 59 bool is_single; 60 60 try -
http/article_entry.cc
r4c1c17d r1a970cd 21 21 22 22 #include "../config.hh" 23 #include "../msg/entity.hh" 23 24 #include "../msg/lexutils.hh" 24 25 #include "../uri.hh" … … 50 51 std::string article_entry::get_author() const 51 52 { 52 msg::msg::const_ptr m = tn->get_article();53 std::string rv = m->get_ field("From", false);53 db::msg::const_ptr m = tn->get_article(); 54 std::string rv = m->get_entity()->get_field("From", false); 54 55 util::strip_crlf(rv); 55 56 return rv; … … 57 58 std::string article_entry::get_title() const 58 59 { 59 msg::msg::const_ptr m = tn->get_article();60 db::msg::const_ptr m = tn->get_article(); 60 61 std::string rv = msg::decode_unstructured 61 (m->get_ field("Subject", false));62 (m->get_entity()->get_field("Subject", false)); 62 63 util::strip_crlf(rv); 63 64 return rv; … … 67 68 article_entry::get_content() const 68 69 { 69 msg::msg::const_ptr m = tn->get_article();70 return m->get_ mime_entity();70 db::msg::const_ptr m = tn->get_article(); 71 return m->get_entity()->get_mime_entity(); 71 72 } 72 73 … … 83 84 boost::posix_time::ptime article_entry::get_date() const 84 85 { 85 msg::msg::const_ptr m = tn->get_article();86 return m-> parsed_date();86 db::msg::const_ptr m = tn->get_article(); 87 return m->get_entity()->parsed_date(); 87 88 } 88 89 boost::posix_time::ptime article_entry::get_updated() const 89 90 { 90 msg::msg::const_ptr m = tn->get_article();91 return m-> parsed_date();91 db::msg::const_ptr m = tn->get_article(); 92 return m->get_entity()->parsed_date(); 92 93 } 93 94 } -
http/compose.cc
r751fac6 r1a970cd 28 28 29 29 #include "../db/db.hh" 30 #include "../db/msg.hh" 30 31 #include "../db/threaded.hh" 31 32 #include "../html/util.hh" 32 33 #include "../logger/logline.hh" 34 #include "../msg/entity.hh" 33 35 #include "../msg/lexutils.hh" 34 #include "../msg/msg.hh"35 36 #include "../msg/text_plain.hh" 37 #include "../msg/util.hh" 36 38 #include "../server.hh" 37 39 #include "../tlate/empty_value.hh" … … 88 90 } 89 91 90 std::string compose::get_followup_uri( msg::msg::const_ptr m)92 std::string compose::get_followup_uri(db::msg::const_ptr m) 91 93 { 92 94 return std::string("/compose?precursor=") + … … 223 225 << "\r\n"; 224 226 225 boost::shared_ptr<msg::msg>m;227 db::msg::ptr m; 226 228 try 227 229 { 228 m .reset(new msg::msg(os.str()));229 m ->complete_mime();230 cb.dbase().file(m, req->get_peer(), usr, cb);230 msg::entity::ptr e(new msg::entity(os.str())); 231 msg::complete_mime(e); 232 m = cb.dbase().file(e, req->get_peer(), usr, cb); 231 233 } 232 234 catch (std::exception &e) … … 291 293 if (req->has_form_field("precursor")) 292 294 { 293 boost::shared_ptr< msg::msg> art;295 boost::shared_ptr<db::msg> art; 294 296 std::string pre = req->get_form_field("precursor"); 295 297 try … … 312 314 void compose::followup(boost::shared_ptr<request> req, 313 315 tlate::data_model::ptr am, 314 boost::shared_ptr< msg::msg> precursor)316 boost::shared_ptr<db::msg> precursor) 315 317 { 316 318 std::string (*const q)(std::string,bool) = html::quote; … … 318 320 319 321 std::string subject = 320 precursor->get_ field("Subject", false);322 precursor->get_entity()->get_field("Subject", false); 321 323 util::strip_crlf(subject); 322 324 if (subject.substr(0, 4) != "Re: ") … … 324 326 am->insert("subject", subject); 325 327 326 std::string fups = precursor->get_ field328 std::string fups = precursor->get_entity()->get_field 327 329 ("Followup-To", false); 328 330 util::strip(fups); 329 331 if (fups.empty() || fups == "poster") // FIXME 330 332 { 331 fups = precursor->get_ field("Newsgroups", false);333 fups = precursor->get_entity()->get_field("Newsgroups", false); 332 334 util::strip(fups); 333 335 } … … 336 338 337 339 #if 0 338 std::string distrib = precursor->get_ field340 std::string distrib = precursor->get_entity()->get_field 339 341 ("Distribution", false); 340 342 util::strip_crlf(distrib); … … 343 345 #endif 344 346 345 std::string refs = precursor->get_ field347 std::string refs = precursor->get_entity()->get_field 346 348 ("References", false); 347 349 util::strip_crlf(refs); … … 375 377 std::ostringstream body; 376 378 377 std::string from = precursor->get_field("From", false); 379 std::string from = 380 precursor->get_entity()->get_field("From", false); 378 381 util::strip_crlf(from); 379 382 body << from << " wrote: \n\n"; 380 383 381 msg::text_plain tp(*precursor );384 msg::text_plain tp(*precursor->get_entity()); 382 385 383 386 for (size_t i = 0; i < tp.num_paras(); i++) -
http/compose.hh
r751fac6 r1a970cd 26 26 #include "../tlate/tlate.hh" 27 27 28 namespace msg { class msg; } 29 namespace db { class group; } 28 namespace db { class msg; class group; } 30 29 31 30 namespace http … … 51 50 void followup(boost::shared_ptr<request>, 52 51 tlate::data_model::ptr, 53 boost::shared_ptr< msg::msg>);52 boost::shared_ptr<db::msg>); 54 53 public: 55 54 compose(server::conn_cb cb) … … 60 59 (boost::shared_ptr<const db::group>); 61 60 static std::string get_followup_uri 62 (boost::shared_ptr<const msg::msg>);61 (boost::shared_ptr<const db::msg>); 63 62 protected: 64 63 void set_attributes(boost::shared_ptr<request>, -
http/group_feed.cc
r4c1c17d r1a970cd 26 26 #include "../config.hh" 27 27 #include "../db/db.hh" 28 #include "../msg/ msg.hh"28 #include "../msg/entity.hh" 29 29 #include "../uri.hh" 30 30 … … 82 82 if (entries.size() > 20) break; 83 83 if (!gr->is_article(i)) continue; 84 msg::msg::const_ptr art = gr->get_article(i);84 db::msg::const_ptr art = gr->get_article(i); 85 85 db::thread_node::const_ptr tn = 86 86 cb.dbase().get_threaded().lookup_msgid … … 88 88 article_entry::ptr ae(new article_entry(tn,u)); 89 89 entries.push_back(ae); 90 boost::posix_time::ptime date = art->parsed_date(); 90 boost::posix_time::ptime date = 91 art->get_entity()->parsed_date(); 91 92 if (latest < date) latest = date; 92 93 } -
http/thread_feed.cc
r72ebe08 r1a970cd 27 27 #include "../db/db.hh" 28 28 #include "../db/threaded.hh" 29 #include "../msg/entity.hh" 29 30 #include "../msg/lexutils.hh" 30 #include "../msg/msg.hh"31 31 #include "../uri.hh" 32 32 … … 56 56 { 57 57 db::user::const_ptr u = req->get_user(); 58 msg::msg::const_ptr m = art->get_article();58 db::msg::const_ptr m = art->get_article(); 59 59 if (m && !m->reading_authz(u)) 60 60 { … … 71 71 db::user::const_ptr u) 72 72 { 73 msg::msg::const_ptr art = m->get_article();73 db::msg::const_ptr art = m->get_article(); 74 74 if (art && art->reading_authz(u)) { 75 75 article_entry::ptr e(new article_entry(m, u)); 76 76 entries.push_front(e); 77 boost::posix_time::ptime date = art->parsed_date(); 77 boost::posix_time::ptime date = 78 art->get_entity()->parsed_date(); 78 79 if (latest < date) latest = date; 79 80 } … … 141 142 std::string thread_feed::get_title() const 142 143 { 143 msg::msg::const_ptr m = art->get_article();144 db::msg::const_ptr m = art->get_article(); 144 145 if (art) { 145 146 return std::string("Thread about ") + 146 msg::decode_unstructured (m->get_field("Subject",147 false));147 msg::decode_unstructured 148 (m->get_entity()->get_field("Subject", false)); 148 149 } else { 149 150 return "untitled thread"; -
local/connection.cc
ra65c1b9 r1a970cd 27 27 #include "../logger/logline.hh" 28 28 #include "../msg/format_violation.hh" 29 #include "../msg/ msg.hh"29 #include "../msg/entity.hh" 30 30 31 31 #include <ios> … … 113 113 } 114 114 115 msg:: msg::ptr m(new msg::msg(ms));115 msg::entity::ptr m(new msg::entity(ms)); 116 116 117 117 // identify action -
msg/entity.cc
re7bbf3c r1a970cd 23 23 #include "multipart.hh" 24 24 #include "text_plain.hh" 25 #include "util.hh" 25 26 26 27 #include "../util.hh" … … 60 61 , field_content(ent.field_content) 61 62 , body(ent.body) 63 , the_date(boost::posix_time::not_a_date_time) 62 64 { 63 65 for (std::list<std::string>::iterator it=field_content.begin(); … … 75 77 std::string default_ct) 76 78 : default_ct(default_ct) 79 , the_date(boost::posix_time::not_a_date_time) 77 80 { 78 81 parse_headers(msgstr); … … 163 166 HEADER_END: 164 167 body = msgstr.substr(inx); 168 } 169 170 boost::posix_time::ptime entity::parsed_date() const 171 { 172 if (the_date == boost::posix_time::not_a_date_time) 173 the_date = parse_date(get_field("Date", false)); 174 return the_date; 165 175 } 166 176 … … 241 251 *it->second = fld; 242 252 } 253 if (name == "date") 254 the_date = boost::posix_time::not_a_date_time; 243 255 } 244 256 -
msg/entity.hh
re7bbf3c r1a970cd 23 23 #include "format_violation.hh" 24 24 #include <boost/algorithm/string/case_conv.hpp> 25 #include <boost/date_time/posix_time/posix_time.hpp> 25 26 #include <boost/shared_ptr.hpp> 26 27 #include <list> … … 45 46 std::string default_ct = 46 47 "text/plain; charset=\"US-ASCII\""); 48 explicit entity(const entity &); 47 49 48 50 virtual ~entity() {} 49 51 50 void validate_format() { 52 boost::posix_time::ptime parsed_date() const; 53 54 void validate_format() const { 51 55 if (!errors.empty()) throw format_violation(errors); 52 56 } … … 87 91 boost::shared_ptr<mime_entity> get_mime_entity() const; 88 92 89 protected:90 explicit entity(const entity &);91 92 93 private: 93 94 std::string default_ct; … … 97 98 std::map<std::string, std::list<std::string>::iterator> fields; 98 99 std::string body; 100 mutable boost::posix_time::ptime the_date; 99 101 100 102 void parse_headers(std::string); -
msg/message_entity.cc
re7bbf3c r1a970cd 20 20 #include "lexutils.hh" 21 21 #include "message_entity.hh" 22 #include " msg.hh"22 #include "util.hh" 23 23 #include "../html/util.hh" 24 24 #include "../tlate/data_model.hh" -
msg/util.cc
r868b365 r1a970cd 1 1 /* This file is part of Alue, the multiprotocol Internet discussion daemon 2 2 3 Copyright © 2009 Antti-Juhani Kaijanaho3 Copyright © 2009, 2010 Antti-Juhani Kaijanaho 4 4 5 5 Alue is free software: you can redistribute it and/or modify it … … 18 18 */ 19 19 20 #include "entity.hh" 21 #include "format_violation.hh" 22 #include "lexutils.hh" 20 23 #include "util.hh" 24 25 #include "../config.hh" 26 #include "../util.hh" 27 28 #include <boost/nondet_random.hpp> 29 30 namespace 31 { 32 void check_present(msg::entity::const_ptr e, std::string hdr) 33 { 34 if (!e->has_field(hdr)) 35 throw msg::format_violation(std::string("The '") + 36 hdr + 37 "' header field is missing" 38 ); 39 } 40 41 void check_absent(msg::entity::const_ptr e, std::string hdr) 42 { 43 if (e->has_field(hdr)) 44 throw msg::format_violation(std::string("The '") + 45 hdr + 46 "' header field is not" 47 " allowed in this context"); 48 } 49 } 21 50 22 51 namespace msg … … 42 71 return rv; 43 72 } 73 74 std::string crlf_canonize(std::string body) 75 { 76 if (!body.empty() && body[body.length()-1] != '\n') 77 body += '\n'; 78 std::string res; 79 for (size_t i = 0; i < body.length(); i++) 80 { 81 switch (body[i]) 82 { 83 case '\r': 84 if (i + 1 == body.length() || body[i+1] != '\n') 85 { 86 res += "\r\n"; 87 continue; 88 } 89 break; 90 case '\n': 91 if (i == 0 || body[i-1] != '\r') 92 { 93 res += "\r\n"; 94 continue; 95 } 96 break; 97 default: 98 ; 99 } 100 res += body[i]; 101 } 102 return res; 103 } 104 105 std::string dot_stuff(std::string body) 106 { 107 std::string rv; 108 for (size_t i = 0; i < body.length(); i++) 109 { 110 if (body[i] == '.' && (i == 0 || body[i-1] == '\n')) 111 rv += ".."; 112 else 113 rv += body[i]; 114 } 115 return rv; 116 } 117 118 std::string dot_destuff(std::string s) 119 { 120 std::string rv; 121 for (size_t i = 0; i < s.length(); i++) 122 { 123 if (s[i] == '.' && (i == 0 || s[i-1] == '\n')) 124 continue; 125 else 126 rv += s[i]; 127 } 128 return rv; 129 } 130 131 boost::posix_time::ptime parse_date(std::string date) 132 { 133 if (date.empty()) return boost::posix_time::ptime(); 134 skip_cfws(date); 135 std::string weekday = get_atom(date, false); 136 skip_cfws(date); 137 std::string day; 138 if (eat_literal(date, ",")) { 139 date.erase(0, 1); 140 skip_cfws(date); 141 day = get_atom(date, false); 142 } else { 143 day = weekday; 144 weekday = ""; 145 } 146 skip_cfws(date); 147 std::string month = util::to_lower(get_atom(date, false)); 148 skip_cfws(date); 149 std::string year = get_atom(date, false); 150 skip_cfws(date); 151 std::string hour = get_atom(date, false); 152 eat_literal(date, ":"); 153 std::string minute = get_atom(date, false); 154 eat_literal(date, ":"); 155 std::string second = get_atom(date, false); 156 skip_cfws(date); 157 std::string tz = "-0000"; 158 if (eat_literal(date, "GMT", false)) { 159 tz = "+0000"; 160 } else if (!date.empty()) { 161 tz = get_atom(date, false); 162 } 163 /* corrections - month */ 164 /**/ if (month == "jan") month = "01"; 165 else if (month == "feb") month = "02"; 166 else if (month == "mar") month = "03"; 167 else if (month == "apr") month = "04"; 168 else if (month == "may") month = "05"; 169 else if (month == "jun") month = "06"; 170 else if (month == "jul") month = "07"; 171 else if (month == "aug") month = "08"; 172 else if (month == "sep") month = "09"; 173 else if (month == "oct") month = "10"; 174 else if (month == "nov") month = "11"; 175 else if (month == "dec") month = "12"; 176 /* other corrections */ 177 if (day.length() == 1) day = "0" + day; 178 if (hour.length() == 1) hour = "0" + hour; 179 if (minute.length() == 1) minute = "0" + minute; 180 if (second.length() == 1) second = "0" + second; 181 if (year.length() == 2) year = "19" + year; 182 if (year.length() == 3) year = "20" + year.substr(1); 183 /* conversion */ 184 std::string str = 185 year + "-" + month + "-" + day + " " + 186 hour + ":" + minute + ":" + second; 187 boost::posix_time::ptime rv; 188 try { 189 rv = boost::posix_time::time_from_string(str); 190 } catch (std::exception &e) { 191 throw format_violation("bad date"); 192 } 193 int tz_h = tz.length() > 2 194 ? (tz[1] - '0') * 10 + (tz[2] - '0') : 0; 195 int tz_m = tz.length() > 4 196 ? (tz[3] - '0') * 10 + (tz[4] - '0') : 0; 197 if (tz.length() > 0 && tz[0] == '-') { 198 rv += boost::posix_time::hours(tz_h); 199 rv += boost::posix_time::minutes(tz_m); 200 } else { 201 rv -= boost::posix_time::hours(tz_h); 202 rv -= boost::posix_time::minutes(tz_m); 203 } 204 return rv; 205 } 206 207 void complete_netnews(entity::ptr e) 208 { 209 check_absent(e, "Injection-Info"); 210 check_absent(e, "Xref"); 211 212 if (!e->has_field("Injection-Date") && 213 (!e->has_field("Date") || !e->has_field("Message-ID"))) 214 { 215 e->replace_field("Injection-Date", 216 util::current_imf_date()); 217 } 218 219 complete_imf(e); 220 } 221 222 void complete_imf(entity::ptr e) 223 { 224 if (!e->has_field("Date")) 225 { 226 e->replace_field("Date", util::current_imf_date()); 227 } 228 229 if (!e->has_field("Message-ID")) 230 { 231 boost::random_device urand; 232 std::ostringstream ss; 233 ss << "<alue." 234 << std::hex 235 << urand() 236 << "." 237 << urand() 238 << "." 239 << urand() 240 << "@" 241 << config["canonical-name"].as<std::string>() 242 << ">"; 243 e->replace_field("Message-ID", ss.str()); 244 } 245 } 246 247 void validate_netnews(entity::const_ptr e) 248 { 249 validate_imf(e); 250 check_present(e, "Message-ID"); 251 check_present(e, "Newsgroups"); 252 check_present(e, "Path"); 253 check_present(e, "Subject"); 254 } 255 256 void validate_imf(entity::const_ptr e) 257 { 258 e->validate_format(); 259 check_present(e, "From"); 260 check_present(e, "Date"); 261 } 262 263 void complete_mime(entity::ptr e) 264 { 265 if (!e->has_field("MIME-Version")) 266 e->replace_field("MIME-Version", "1.0"); 267 268 bool sevenbit = true; 269 std::string body = e->get_body(); 270 for (size_t i = 0; i < body.length(); i++) 271 if (unsigned(body[i]) >= 0x80) 272 { 273 sevenbit = false; 274 break; 275 } 276 277 if (!e->has_field("Content-Type")) 278 e->replace_field("Content-Type", 279 std::string("text/plain; charset=") + 280 (sevenbit ? "us-ascii" : "utf-8")); 281 282 if (!e->has_field("Content-Transfer-Encoding")) 283 e->replace_field("Content-Transfer-Encoding", 284 sevenbit ? "7bit" : "8bit"); 285 } 44 286 } -
msg/util.hh
r868b365 r1a970cd 1 1 /* This file is part of Alue, the multiprotocol Internet discussion daemon 2 2 3 Copyright © 2009 Antti-Juhani Kaijanaho3 Copyright © 2009, 2010 Antti-Juhani Kaijanaho 4 4 5 5 Alue is free software: you can redistribute it and/or modify it … … 21 21 #define GUARD_MSG_UTIL_HH 22 22 23 #include <boost/date_time/posix_time/posix_time.hpp> 24 #include <boost/shared_ptr.hpp> 23 25 #include <string> 24 26 25 27 namespace msg 26 28 { 29 class entity; 30 27 31 std::string quote(std::string s); 32 33 std::string crlf_canonize(std::string); 34 std::string dot_stuff(std::string); 35 std::string dot_destuff(std::string); 36 boost::posix_time::ptime parse_date(std::string date); 37 38 void complete_mime(boost::shared_ptr<entity>); 39 void complete_netnews(boost::shared_ptr<entity>); 40 void complete_imf(boost::shared_ptr<entity>); 41 void validate_netnews(boost::shared_ptr<const entity>); 42 void validate_imf(boost::shared_ptr<const entity>); 28 43 } 29 44 -
nntp/article.cc
r563ece2 r1a970cd 22 22 23 23 #include "../db/db.hh" 24 #include "../db/msg.hh" 24 25 #include "../db/user.hh" 25 #include "../msg/msg.hh" 26 #include "../msg/entity.hh" 27 #include "../msg/util.hh" 26 28 27 29 namespace nntp … … 76 78 77 79 78 boost::shared_ptr< msg::msg> message;80 boost::shared_ptr<db::msg> message; 79 81 std::string msgnum = "0"; 80 82 try { … … 160 162 if (cmd == HEAD || cmd == ARTICLE) 161 163 { 162 std::string head = message->get_ header();164 std::string head = message->get_entity()->get_header(); 163 165 c.send_raw(head.begin(), head.end()); 164 166 c.send_line(message->get_xref_field(true)); … … 167 169 if (cmd == ARTICLE || cmd == BODY) 168 170 { 169 std::string b = msg::dot_stuff(message->get_body()); 171 std::string b = msg::dot_stuff 172 (message->get_entity()->get_body()); 170 173 c.send_raw(b.begin(), b.end()); 171 174 } -
nntp/hdr.cc
r868b365 r1a970cd 1 1 /* This file is part of Alue, the multiprotocol Internet discussion daemon 2 2 3 Copyright © 2009 Antti-Juhani Kaijanaho3 Copyright © 2009, 2010 Antti-Juhani Kaijanaho 4 4 5 5 Alue is free software: you can redistribute it and/or modify it … … 23 23 24 24 #include "../db/db.hh" 25 #include "../msg/msg.hh" 25 #include "../db/msg.hh" 26 #include "../msg/entity.hh" 26 27 27 28 namespace nntp … … 47 48 std::string hname, 48 49 db::group::number, 49 boost::shared_ptr< msg::msg> m) const;50 boost::shared_ptr<db::msg> m) const; 50 51 51 52 cmd_type cmd; … … 67 68 if (args[1][0] == '<') 68 69 { 69 boost::shared_ptr< msg::msg> m;70 boost::shared_ptr<db::msg> m; 70 71 try 71 72 { … … 127 128 std::string hname, 128 129 db::group::number artnum, 129 boost::shared_ptr< msg::msg> m)130 boost::shared_ptr<db::msg> m) 130 131 const 131 132 { … … 140 141 if (hn == "lines" || hn == ":lines") 141 142 s = boost::lexical_cast<std::string> 142 (m->get_ body_lines());143 (m->get_entity()->get_body_lines()); 143 144 else if (hn == "bytes" || hn == ":bytes") 144 145 s = boost::lexical_cast<std::string> 145 (m->get_ size() +146 (m->get_entity()->get_size() + 146 147 m->get_xref_field(true).length() + 2); 147 148 else 148 s = m->get_ field(hname, false);149 s = m->get_entity()->get_field(hname, false); 149 150 over_output_header(os, s); 150 151 c.send_line(os.str()); -
nntp/last.cc
r868b365 r1a970cd 1 1 /* This file is part of Alue, the multiprotocol Internet discussion daemon 2 2 3 Copyright © 2009 Antti-Juhani Kaijanaho3 Copyright © 2009, 2010 Antti-Juhani Kaijanaho 4 4 5 5 Alue is free software: you can redistribute it and/or modify it … … 21 21 22 22 #include "../db/group.hh" 23 #include "../ msg/msg.hh"23 #include "../db/msg.hh" 24 24 25 25 namespace nntp -
nntp/next.cc
r868b365 r1a970cd 1 1 /* This file is part of Alue, the multiprotocol Internet discussion daemon 2 2 3 Copyright © 2009 Antti-Juhani Kaijanaho3 Copyright © 2009, 2010 Antti-Juhani Kaijanaho 4 4 5 5 Alue is free software: you can redistribute it and/or modify it … … 21 21 22 22 #include "../db/group.hh" 23 #include "../ msg/msg.hh"23 #include "../db/msg.hh" 24 24 25 25 namespace nntp -
nntp/over.cc
r71e633d r1a970cd 23 23 24 24 #include "../db/db.hh" 25 #include "../msg/msg.hh" 25 #include "../db/msg.hh" 26 #include "../msg/entity.hh" 26 27 27 28 namespace nntp … … 46 47 void write_article_line(connection::cb, 47 48 db::group::number, 48 boost::shared_ptr< msg::msg> m) const;49 boost::shared_ptr<db::msg> m) const; 49 50 50 51 cmd_type cmd; … … 68 69 if (args[0][0] == '<') 69 70 { 70 boost::shared_ptr< msg::msg> m;71 boost::shared_ptr<db::msg> m; 71 72 try 72 73 { … … 133 134 void over::write_article_line(connection::cb c, 134 135 db::group::number artnum, 135 boost::shared_ptr< msg::msg> m)136 boost::shared_ptr<db::msg> m) 136 137 const 137 138 { … … 151 152 if (full) s = hname + ": "; 152 153 s += boost::lexical_cast<std::string> 153 (m->get_ body_lines());154 (m->get_entity()->get_body_lines()); 154 155 } 155 156 else if (hn == "bytes" || hn == ":bytes") … … 157 158 if (full) s = hname + ": "; 158 159 s += boost::lexical_cast<std::string> 159 (m->get_ size());160 (m->get_entity()->get_size()); 160 161 } 161 162 else 162 s = m->get_ field(hname, full);163 s = m->get_entity()->get_field(hname, full); 163 164 164 165 over_output_header(os, s); -
nntp/post.cc
r4c34ee2 r1a970cd 21 21 22 22 #include "../db/db.hh" 23 #include "../db/msg.hh" 23 24 #include "../logger/logline.hh" 24 #include "../msg/msg.hh" 25 #include "../msg/entity.hh" 26 #include "../msg/util.hh" 25 27 26 28 namespace … … 37 39 connection::continuation::ptr read_handler::operator()(std::string data) 38 40 { 39 boost::shared_ptr<msg::msg>m;41 db::msg::ptr m; 40 42 try { 41 m.reset(new msg::msg(msg::dot_destuff(data))); 42 c.dbase().file(m, c.peer(), c.identity(), c.srv_cb()); 43 msg::entity::ptr e 44 (new msg::entity(msg::dot_destuff(data))); 45 m = c.dbase().file(e, c.peer(), c.identity(), 46 c.srv_cb()); 43 47 } catch (std::exception &e) { 44 48 std::ostringstream ss; -
smtp_client/smtp_client.cc
rae733bf r1a970cd 22 22 #include "../config.hh" 23 23 #include "../logger/logline.hh" 24 #include "../msg/msg.hh" 24 #include "../msg/entity.hh" 25 #include "../msg/util.hh" 26 #include "../util.hh" 25 27 26 28 #include <boost/algorithm/string/case_conv.hpp> … … 37 39 { 38 40 message = msg::crlf_canonize(message); 39 boost::shared_ptr<msg::msg>msg40 (new msg:: msg(msg::dot_destuff(message)));41 msg ->complete_imf();42 msg ->complete_mime();41 msg::entity::ptr msg 42 (new msg::entity(msg::dot_destuff(message))); 43 msg::complete_imf(msg); 44 msg::complete_mime(msg); 43 45 message = msg::dot_stuff(msg->get_entity()); 44 46 -
tlate/date_value.cc
rc04e3c7 r1a970cd 30 30 #include "../msg/lexutils.hh" 31 31 #include "../msg/mime_entity.hh" 32 #include "../msg/msg.hh"33 32 #include "../uri.hh" 34 33 -
tlate/msg_value.cc
re7bbf3c r1a970cd 28 28 29 29 #include "../db/threaded.hh" 30 #include "../db/msg.hh" 30 31 #include "../html/util.hh" 31 32 #include "../http/compose.hh" 33 #include "../msg/entity.hh" 32 34 #include "../msg/lexutils.hh" 33 35 #include "../msg/mime_entity.hh" 34 #include "../msg/msg.hh"35 36 #include "../uri.hh" 36 37 … … 44 45 class xref_seq : public sequential_value 45 46 { 46 msg::msg::const_ptr m;47 db::msg::const_ptr m; 47 48 db::user::const_ptr u; 48 49 49 50 class vit : public virtual_iterator 50 51 { 51 msg::msg::xref_type::const_iterator it;52 db::msg::xref_type::const_iterator it; 52 53 mutable value::const_ptr cur; 53 54 db::user::const_ptr u; 54 55 55 vit( msg::msg::xref_type::const_iterator it,56 vit(db::msg::xref_type::const_iterator it, 56 57 value::const_ptr cur, 57 58 db::user::const_ptr u) … … 61 62 {} 62 63 public: 63 vit( msg::msg::xref_type::const_iterator it,64 vit(db::msg::xref_type::const_iterator it, 64 65 db::user::const_ptr u) 65 66 : it(it) … … 85 86 86 87 public: 87 xref_seq( msg::msg::const_ptr m, db::user::const_ptr u)88 xref_seq(db::msg::const_ptr m, db::user::const_ptr u) 88 89 : m(m) 89 90 , u(u) … … 130 131 using html::quote; 131 132 typedef string_value sv; 132 msg::msg::const_ptr m = tn->get_article(); 133 db::msg::const_ptr m = tn->get_article(); 134 msg::entity::const_ptr e = m->get_entity(); 133 135 std::string msgid = tn->get_msgid(); 134 136 bool rauthz = m ? m->reading_authz(u) : false; … … 157 159 else if (rauthz && m && var == "from") 158 160 rv.reset(new sv(quote(decode_unstructured 159 ( m->get_field("From", false)),161 (e->get_field("From", false)), 160 162 !authn))); 161 163 else if (rauthz && m && var == "subject") 162 164 rv.reset(new sv(quote(decode_unstructured 163 ( m->get_field("Subject", false)),165 (e->get_field("Subject", false)), 164 166 !authn))); 165 167 else if (rauthz && m && var == "date") 166 rv.reset(new date_value( m->parsed_date()));168 rv.reset(new date_value(e->parsed_date())); 167 169 else if (rauthz && var == "latest-date" && 168 170 !tn->get_latest_date().is_special()) … … 170 172 171 173 else if (rauthz && m && var == "header") 172 rv.reset(new header_value( m,!u));174 rv.reset(new header_value(e,!u)); 173 175 else if (rauthz && m && var == "body") 174 176 { 175 msg::mime_entity::const_ptr me = m->get_mime_entity();177 msg::mime_entity::const_ptr me = e->get_mime_entity(); 176 178 rv = me->get_tlate_value(authn); 177 179 }
