Changeset 1a970cd0640f976f152341597a5249ec22acbba7

Show
Ignore:
Timestamp:
09/05/10 21:25:41 (21 months ago)
Author:
Antti-Juhani Kaijanaho <antti-juhani@…>
Children:
c53e53f1cb0d542e5c931555a591d2589c033006
Parents:
e7bbf3c6b857df8ad33c4d39396d693b48a48461
git-committer:
Antti-Juhani Kaijanaho <antti-juhani@…> (09/05/10 21:25:41)
Message:

[msg::msg] Separate out db::msg and let msg::entity handle the rest

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

Files:
1 added
1 removed
28 modified
1 moved

Legend:

Unmodified
Added
Removed
  • db/db.cc

    r7ccc366 r1a970cd  
    2020#include "db.hh" 
    2121#include "db_reader.hh" 
     22#include "msg.hh" 
    2223#include "role.hh" 
    2324#include "role_exists.hh" 
     
    2728#include "../config.hh" 
    2829#include "../logger/logline.hh" 
    29 #include "../msg/msg.hh" 
     30#include "../msg/entity.hh" 
     31#include "../msg/util.hh" 
    3032#include "../myassert.hh" 
    3133#include "../util.hh" 
     
    220222                 
    221223                std::string msgstr =  
    222                         msg::dot_destuff(msg::crlf_canonize(ss.str())); 
     224                        ::msg::dot_destuff(::msg::crlf_canonize(ss.str())); 
    223225 
    224226                // 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)); 
    226229                for (std::map<std::string, group::number>::const_iterator it =  
    227230                             xref.begin(); 
     
    309312        } 
    310313 
    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) 
    315318        { 
    316319                // first, perform USEPRO-14 (USEFOR-12) injector duties 
    317320 
    318                 mg->complete_netnews(); 
     321                ::msg::complete_netnews(ent); 
    319322 
    320323                std::string server_name =  
     
    330333                           << source.to_string() 
    331334                           << "\""; 
    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); 
    336339                util::strip_crlf(path); 
    337340                if (path.empty()) 
     
    349352                path = server_name +  
    350353                        " !.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)); 
    354359 
    355360                boost::lock_guard<boost::recursive_mutex> lg(mt); 
     
    432437                } 
    433438                dbfile << "FOLLOWS\n" 
    434                        << msg::dot_stuff(mg->get_entity()) 
     439                       << ::msg::dot_stuff(mg->get_entity()->get_entity()) 
    435440                       << ".END\n"; 
    436441                dbfile.close(); 
     442                return mg; 
    437443        } 
    438444 
  • db/db.hh

    r7ccc366 r1a970cd  
    3535#include <fstream> 
    3636 
    37 namespace msg { class msg; } 
     37namespace msg { class entity; } 
    3838 
    3939namespace db 
    4040{ 
     41        class msg; 
    4142        class user; 
    4243        class password_handler; 
     
    5253                typedef std::map<std::string,boost::shared_ptr<group> > 
    5354                ::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> > 
    5556                ::const_iterator  msgid_iterator; 
    5657 
     
    6768                msgid_iterator msgids_end() const { return msgid.end(); } 
    6869 
    69                 boost::shared_ptr<msg::msg> lookup_msgid(std::string s)  { 
     70                boost::shared_ptr<msg> lookup_msgid(std::string s)  { 
    7071                        boost::lock_guard<boost::recursive_mutex> lg(mt); 
    7172                        msgid_iterator it = msgid.find(s); 
     
    8182                } 
    8283 
    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); 
    8788 
    8889                const threaded &get_threaded() { 
     
    120121                std::map<std::string, boost::shared_ptr<role> > roles; 
    121122                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; 
    123124 
    124125                std::string dbname; 
  • db/group.cc

    re044cc7 r1a970cd  
    2424 
    2525#include "../config.hh" 
    26 #include "../msg/msg.hh" 
     26#include "../msg/entity.hh" 
    2727#include "../smtp_client/smtp_client.hh" 
    2828 
     
    6969                if (recv.empty()) return rv; 
    7070 
    71                 msg::msg::ptr nm(new msg::msg(*m)); 
     71                ::msg::entity::ptr nm(new ::msg::entity(*m->get_entity())); 
    7272                { 
    7373                        std::string subject = nm->get_field("subject", false); 
  • db/group.hh

    r4c34ee2 r1a970cd  
    3434#include <vector> 
    3535 
    36 namespace msg { class msg; } 
    37  
    3836namespace db 
    3937{ 
    4038        class db; 
     39        class msg; 
    4140        class role; 
    4241        class threaded_group; 
     
    7271                bool is_article(number n) const { return retrieve(n); } 
    7372 
    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); 
    7675                        if (!rv) throw no_such_article(); 
    7776                        return rv; 
    7877                } 
    7978 
    80                 number file(boost::shared_ptr<msg::msg> m, server::conn_cb); 
     79                number file(boost::shared_ptr<msg> m, server::conn_cb); 
    8180 
    82                 void file(boost::shared_ptr<msg::msg> m, number n); 
     81                void file(boost::shared_ptr<msg> m, number n); 
    8382 
    8483                number get_count() const { return count; } 
     
    114113                 
    115114                size_t displacement; 
    116                 std::vector<boost::shared_ptr<msg::msg> > msgs; 
     115                std::vector<boost::shared_ptr<msg> > msgs; 
    117116 
    118117                std::set<boost::shared_ptr<role> > readers; 
     
    122121                                  const std::set<boost::shared_ptr<role> > &); 
    123122 
    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; 
    126125                        if (n < displacement) return null; 
    127126                        if (n - displacement >= msgs.size()) return null; 
  • db/msg.hh

    r4c1c17d r1a970cd  
    2121#define GUARD_MSG_MSG_HH 
    2222 
    23 #include "entity.hh" 
    24  
    2523#include "../db/article_number_type.hh" 
    2624#include "../util.hh" 
     
    2826#include <boost/shared_ptr.hpp> 
    2927#include <boost/tuple/tuple.hpp> 
    30 #include <boost/date_time/posix_time/posix_time.hpp> 
     28#include <list> 
     29#include <map> 
    3130 
    32 namespace db { class group; class user; class thread_node; } 
     31namespace msg { class entity; } 
    3332 
    34 namespace msg 
     33namespace db 
    3534{ 
    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); 
    4035 
    41         class msg : public entity 
     36        class group; class user; class thread_node; 
     37 
     38        class msg 
    4239        { 
    4340        public: 
     
    4542                typedef boost::shared_ptr<const msg> const_ptr; 
    4643 
    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> 
    4946                xref_type; 
    5047 
    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 >); 
    5351 
    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; } 
    6354 
    6455                std::list<std::string> get_newsgroups() const; 
    6556 
    66                 void replace_field(std::string name, std::string body); 
    67  
    6857                const xref_type &get_xref() const 
    69                         { return the_xref; }  
     58                        { return the_xref; } 
    7059 
    7160                std::string get_xref_field(bool full) const; 
    7261 
    7362                std::string msgid() const { return the_msgid; } 
    74                 void set_msgid(); 
    7563 
    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) 
    7866                        { the_xref[gr] = n; } 
    7967 
    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; 
    8270        private: 
    8371                std::string the_msgid; 
    84                 boost::posix_time::ptime the_date; 
    8572                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; 
    8974        }; 
    9075         
  • db/threaded.cc

    re1af652 r1a970cd  
    2020#include "threaded.hh" 
    2121 
     22#include "../msg/entity.hh" 
    2223#include "../msg/lexutils.hh" 
    23 #include "../msg/msg.hh" 
    2424#include "../html/util.hh" 
    2525#include "../tlate/sequential_value.hh" 
     
    159159                grinx = grinx_; 
    160160                art = art_; 
    161                 my_date = art->parsed_date(); 
     161                my_date = art->get_entity()->parsed_date(); 
    162162                if (latest_date < my_date) 
    163163                        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); 
    165166                ptr prev; 
    166167                while (!refss.empty()) 
    167168                { 
    168                         std::string ref = msg::get_msgid(refss); 
     169                        std::string ref = ::msg::get_msgid(refss); 
    169170                        if (ref.empty()) continue; 
    170171                        ptr &tn = msgids[ref]; 
  • db/threaded.hh

    r299b297 r1a970cd  
    2222 
    2323#include "group.hh" 
     24#include "msg.hh" 
    2425 
    25 #include "../msg/msg.hh" 
    2626#include "../tlate/tlate.hh" 
    2727 
     
    4242                std::string msgid; 
    4343                group::number grinx; 
    44                 boost::shared_ptr<msg::msg> art; 
     44                boost::shared_ptr<msg> art; 
    4545                boost::posix_time::ptime my_date, latest_date; 
    4646                std::list<ptr> children; 
     
    7777 
    7878                void add_msg(group::number grinx, 
    79                              boost::shared_ptr<msg::msg> art); 
     79                             boost::shared_ptr<msg> art); 
    8080                void prune(); 
    8181                bool has_descendant(ptr); 
     
    9090                } 
    9191                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; } 
    9393                template <typename Cmp> 
    9494                void sort_children(Cmp cmp) { 
     
    146146 
    147147                void add_msg(group::number grinx,  
    148                              boost::shared_ptr<msg::msg> art); 
     148                             boost::shared_ptr<msg> art); 
    149149                const std::list<thread_node::ptr> &get_threads() const 
    150150                        { return root->get_children(); } 
  • db/user.cc

    r92c18c1 r1a970cd  
    151151                mam->insert("from", from); 
    152152                mam->insert("to", 
    153                             msg::make_phrase(ton) + " <" + to + ">"); 
     153                            ::msg::make_phrase(ton) + " <" + to + ">"); 
    154154                mam->insert("userid", userid); 
    155155                mam->insert("link", link.str()); 
  • http/article.cc

    r654bb60 r1a970cd  
    2525 
    2626#include "../db/db.hh" 
     27#include "../db/msg.hh" 
    2728#include "../db/threaded.hh" 
    2829#include "../html/util.hh" 
    2930#include "../msg/content_type.hh" 
    3031#include "../msg/lexutils.hh" 
    31 #include "../msg/msg.hh" 
    3232#include "../msg/text_plain.hh" 
    3333#include "../server.hh" 
     
    5656                                     tlate::data_model::ptr am) 
    5757        { 
    58                 boost::shared_ptr<msg::msg> art; 
     58                boost::shared_ptr<db::msg> art; 
    5959                bool is_single; 
    6060                try 
  • http/article_entry.cc

    r4c1c17d r1a970cd  
    2121 
    2222#include "../config.hh" 
     23#include "../msg/entity.hh" 
    2324#include "../msg/lexutils.hh" 
    2425#include "../uri.hh" 
     
    5051        std::string article_entry::get_author() const 
    5152        { 
    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); 
    5455                util::strip_crlf(rv); 
    5556                return rv; 
     
    5758        std::string article_entry::get_title() const 
    5859        { 
    59                 msg::msg::const_ptr m = tn->get_article(); 
     60                db::msg::const_ptr m = tn->get_article(); 
    6061                std::string rv = msg::decode_unstructured 
    61                         (m->get_field("Subject", false)); 
     62                        (m->get_entity()->get_field("Subject", false)); 
    6263                util::strip_crlf(rv); 
    6364                return rv; 
     
    6768        article_entry::get_content() const 
    6869        { 
    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(); 
    7172        } 
    7273 
     
    8384        boost::posix_time::ptime article_entry::get_date() const 
    8485        { 
    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(); 
    8788        } 
    8889        boost::posix_time::ptime article_entry::get_updated() const 
    8990        { 
    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(); 
    9293        } 
    9394} 
  • http/compose.cc

    r751fac6 r1a970cd  
    2828 
    2929#include "../db/db.hh" 
     30#include "../db/msg.hh" 
    3031#include "../db/threaded.hh" 
    3132#include "../html/util.hh" 
    3233#include "../logger/logline.hh" 
     34#include "../msg/entity.hh" 
    3335#include "../msg/lexutils.hh" 
    34 #include "../msg/msg.hh" 
    3536#include "../msg/text_plain.hh" 
     37#include "../msg/util.hh" 
    3638#include "../server.hh" 
    3739#include "../tlate/empty_value.hh" 
     
    8890        } 
    8991 
    90         std::string compose::get_followup_uri(msg::msg::const_ptr m) 
     92        std::string compose::get_followup_uri(db::msg::const_ptr m) 
    9193        { 
    9294                return std::string("/compose?precursor=") + 
     
    223225                   << "\r\n"; 
    224226 
    225                 boost::shared_ptr<msg::msg> m; 
     227                db::msg::ptr m; 
    226228                try 
    227229                { 
    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); 
    231233                } 
    232234                catch (std::exception &e) 
     
    291293                if (req->has_form_field("precursor")) 
    292294                { 
    293                         boost::shared_ptr<msg::msg> art; 
     295                        boost::shared_ptr<db::msg> art; 
    294296                        std::string pre = req->get_form_field("precursor"); 
    295297                        try 
     
    312314        void compose::followup(boost::shared_ptr<request> req, 
    313315                               tlate::data_model::ptr am, 
    314                                boost::shared_ptr<msg::msg> precursor) 
     316                               boost::shared_ptr<db::msg> precursor) 
    315317        { 
    316318                std::string (*const q)(std::string,bool) = html::quote; 
     
    318320 
    319321                std::string subject =  
    320                         precursor->get_field("Subject", false); 
     322                        precursor->get_entity()->get_field("Subject", false); 
    321323                util::strip_crlf(subject); 
    322324                if (subject.substr(0, 4) != "Re: ") 
     
    324326                am->insert("subject", subject); 
    325327 
    326                 std::string fups = precursor->get_field 
     328                std::string fups = precursor->get_entity()->get_field 
    327329                        ("Followup-To", false); 
    328330                util::strip(fups); 
    329331                if (fups.empty() || fups == "poster") // FIXME 
    330332                { 
    331                         fups = precursor->get_field("Newsgroups", false); 
     333                        fups = precursor->get_entity()->get_field("Newsgroups", false); 
    332334                        util::strip(fups); 
    333335                } 
     
    336338 
    337339#if 0 
    338                 std::string distrib = precursor->get_field 
     340                std::string distrib = precursor->get_entity()->get_field 
    339341                        ("Distribution", false); 
    340342                util::strip_crlf(distrib); 
     
    343345#endif 
    344346 
    345                 std::string refs = precursor->get_field 
     347                std::string refs = precursor->get_entity()->get_field 
    346348                        ("References", false); 
    347349                util::strip_crlf(refs); 
     
    375377                std::ostringstream body; 
    376378 
    377                 std::string from = precursor->get_field("From", false); 
     379                std::string from = 
     380                        precursor->get_entity()->get_field("From", false); 
    378381                util::strip_crlf(from); 
    379382                body << from << " wrote: \n\n"; 
    380383 
    381                 msg::text_plain tp(*precursor); 
     384                msg::text_plain tp(*precursor->get_entity()); 
    382385 
    383386                for (size_t i = 0; i < tp.num_paras(); i++) 
  • http/compose.hh

    r751fac6 r1a970cd  
    2626#include "../tlate/tlate.hh" 
    2727 
    28 namespace msg { class msg; } 
    29 namespace db { class group; } 
     28namespace db { class msg; class group; } 
    3029 
    3130namespace http 
     
    5150                void followup(boost::shared_ptr<request>, 
    5251                              tlate::data_model::ptr, 
    53                               boost::shared_ptr<msg::msg>);         
     52                              boost::shared_ptr<db::msg>);         
    5453        public: 
    5554                compose(server::conn_cb cb)  
     
    6059                (boost::shared_ptr<const db::group>); 
    6160                static std::string get_followup_uri 
    62                 (boost::shared_ptr<const msg::msg>); 
     61                (boost::shared_ptr<const db::msg>); 
    6362        protected: 
    6463                void set_attributes(boost::shared_ptr<request>, 
  • http/group_feed.cc

    r4c1c17d r1a970cd  
    2626#include "../config.hh" 
    2727#include "../db/db.hh" 
    28 #include "../msg/msg.hh" 
     28#include "../msg/entity.hh" 
    2929#include "../uri.hh" 
    3030 
     
    8282                        if (entries.size() > 20) break; 
    8383                        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); 
    8585                        db::thread_node::const_ptr tn = 
    8686                                cb.dbase().get_threaded().lookup_msgid 
     
    8888                        article_entry::ptr ae(new article_entry(tn,u)); 
    8989                        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(); 
    9192                        if (latest < date) latest = date; 
    9293                } 
  • http/thread_feed.cc

    r72ebe08 r1a970cd  
    2727#include "../db/db.hh" 
    2828#include "../db/threaded.hh" 
     29#include "../msg/entity.hh" 
    2930#include "../msg/lexutils.hh" 
    30 #include "../msg/msg.hh" 
    3131#include "../uri.hh" 
    3232 
     
    5656        { 
    5757                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(); 
    5959                if (m && !m->reading_authz(u)) 
    6060                { 
     
    7171                                  db::user::const_ptr u) 
    7272        { 
    73                 msg::msg::const_ptr art = m->get_article(); 
     73                db::msg::const_ptr art = m->get_article(); 
    7474                if (art && art->reading_authz(u)) { 
    7575                        article_entry::ptr e(new article_entry(m, u)); 
    7676                        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(); 
    7879                        if (latest < date) latest = date; 
    7980                } 
     
    141142        std::string thread_feed::get_title() const 
    142143        { 
    143                 msg::msg::const_ptr m = art->get_article(); 
     144                db::msg::const_ptr m = art->get_article(); 
    144145                if (art) { 
    145146                        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)); 
    148149                } else { 
    149150                        return "untitled thread"; 
  • local/connection.cc

    ra65c1b9 r1a970cd  
    2727#include "../logger/logline.hh" 
    2828#include "../msg/format_violation.hh" 
    29 #include "../msg/msg.hh" 
     29#include "../msg/entity.hh" 
    3030 
    3131#include <ios> 
     
    113113                        } 
    114114 
    115                         msg::msg::ptr m(new msg::msg(ms)); 
     115                        msg::entity::ptr m(new msg::entity(ms)); 
    116116 
    117117                        // identify action 
  • msg/entity.cc

    re7bbf3c r1a970cd  
    2323#include "multipart.hh" 
    2424#include "text_plain.hh" 
     25#include "util.hh" 
    2526 
    2627#include "../util.hh" 
     
    6061                , field_content(ent.field_content) 
    6162                , body(ent.body) 
     63                , the_date(boost::posix_time::not_a_date_time) 
    6264        { 
    6365                for (std::list<std::string>::iterator it=field_content.begin(); 
     
    7577                       std::string default_ct) 
    7678                : default_ct(default_ct) 
     79                , the_date(boost::posix_time::not_a_date_time) 
    7780        { 
    7881                parse_headers(msgstr); 
     
    163166        HEADER_END: 
    164167                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; 
    165175        } 
    166176 
     
    241251                        *it->second = fld; 
    242252                } 
     253                if (name == "date") 
     254                        the_date = boost::posix_time::not_a_date_time; 
    243255        } 
    244256 
  • msg/entity.hh

    re7bbf3c r1a970cd  
    2323#include "format_violation.hh" 
    2424#include <boost/algorithm/string/case_conv.hpp> 
     25#include <boost/date_time/posix_time/posix_time.hpp> 
    2526#include <boost/shared_ptr.hpp> 
    2627#include <list> 
     
    4546                                std::string default_ct =  
    4647                                "text/plain; charset=\"US-ASCII\""); 
     48                explicit entity(const entity &); 
    4749 
    4850                virtual ~entity() {} 
    4951 
    50                 void validate_format() { 
     52                boost::posix_time::ptime parsed_date() const; 
     53 
     54                void validate_format() const { 
    5155                        if (!errors.empty()) throw format_violation(errors); 
    5256                } 
     
    8791                boost::shared_ptr<mime_entity> get_mime_entity() const; 
    8892 
    89         protected: 
    90                 explicit entity(const entity &); 
    91  
    9293        private: 
    9394                std::string default_ct; 
     
    9798                std::map<std::string, std::list<std::string>::iterator> fields; 
    9899                std::string body; 
     100                mutable boost::posix_time::ptime the_date; 
    99101 
    100102                void parse_headers(std::string); 
  • msg/message_entity.cc

    re7bbf3c r1a970cd  
    2020#include "lexutils.hh" 
    2121#include "message_entity.hh" 
    22 #include "msg.hh" 
     22#include "util.hh" 
    2323#include "../html/util.hh" 
    2424#include "../tlate/data_model.hh" 
  • msg/util.cc

    r868b365 r1a970cd  
    11/*  This file is part of Alue, the multiprotocol Internet discussion daemon 
    22 
    3     Copyright © 2009 Antti-Juhani Kaijanaho 
     3    Copyright © 2009, 2010 Antti-Juhani Kaijanaho 
    44 
    55    Alue is free software: you can redistribute it and/or modify it 
     
    1818 */ 
    1919 
     20#include "entity.hh" 
     21#include "format_violation.hh" 
     22#include "lexutils.hh" 
    2023#include "util.hh" 
     24 
     25#include "../config.hh" 
     26#include "../util.hh" 
     27 
     28#include <boost/nondet_random.hpp> 
     29 
     30namespace 
     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} 
    2150 
    2251namespace msg 
     
    4271                return rv; 
    4372        } 
     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        } 
    44286} 
  • msg/util.hh

    r868b365 r1a970cd  
    11/*  This file is part of Alue, the multiprotocol Internet discussion daemon 
    22 
    3     Copyright © 2009 Antti-Juhani Kaijanaho 
     3    Copyright © 2009, 2010 Antti-Juhani Kaijanaho 
    44 
    55    Alue is free software: you can redistribute it and/or modify it 
     
    2121#define GUARD_MSG_UTIL_HH 
    2222 
     23#include <boost/date_time/posix_time/posix_time.hpp> 
     24#include <boost/shared_ptr.hpp> 
    2325#include <string> 
    2426 
    2527namespace msg 
    2628{ 
     29        class entity; 
     30 
    2731        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>); 
    2843} 
    2944 
  • nntp/article.cc

    r563ece2 r1a970cd  
    2222 
    2323#include "../db/db.hh" 
     24#include "../db/msg.hh" 
    2425#include "../db/user.hh" 
    25 #include "../msg/msg.hh" 
     26#include "../msg/entity.hh" 
     27#include "../msg/util.hh" 
    2628 
    2729namespace nntp 
     
    7678 
    7779 
    78                 boost::shared_ptr<msg::msg> message; 
     80                boost::shared_ptr<db::msg> message; 
    7981                std::string msgnum = "0"; 
    8082                try { 
     
    160162                if (cmd == HEAD || cmd == ARTICLE) 
    161163                { 
    162                         std::string head = message->get_header(); 
     164                        std::string head = message->get_entity()->get_header(); 
    163165                        c.send_raw(head.begin(), head.end()); 
    164166                        c.send_line(message->get_xref_field(true)); 
     
    167169                if (cmd == ARTICLE || cmd == BODY) 
    168170                { 
    169                         std::string b = msg::dot_stuff(message->get_body()); 
     171                        std::string b = msg::dot_stuff 
     172                                (message->get_entity()->get_body()); 
    170173                        c.send_raw(b.begin(), b.end()); 
    171174                } 
  • nntp/hdr.cc

    r868b365 r1a970cd  
    11/*  This file is part of Alue, the multiprotocol Internet discussion daemon 
    22 
    3     Copyright © 2009 Antti-Juhani Kaijanaho 
     3    Copyright © 2009, 2010 Antti-Juhani Kaijanaho 
    44 
    55    Alue is free software: you can redistribute it and/or modify it 
     
    2323 
    2424#include "../db/db.hh" 
    25 #include "../msg/msg.hh" 
     25#include "../db/msg.hh" 
     26#include "../msg/entity.hh" 
    2627 
    2728namespace nntp 
     
    4748                                        std::string hname, 
    4849                                        db::group::number, 
    49                                         boost::shared_ptr<msg::msg> m) const; 
     50                                        boost::shared_ptr<db::msg> m) const; 
    5051 
    5152                cmd_type cmd; 
     
    6768                        if (args[1][0] == '<') 
    6869                        { 
    69                                 boost::shared_ptr<msg::msg> m; 
     70                                boost::shared_ptr<db::msg> m; 
    7071                                try 
    7172                                { 
     
    127128                                     std::string hname, 
    128129                                     db::group::number artnum, 
    129                                      boost::shared_ptr<msg::msg> m) 
     130                                     boost::shared_ptr<db::msg> m) 
    130131                const 
    131132        { 
     
    140141                if (hn == "lines" || hn == ":lines") 
    141142                        s = boost::lexical_cast<std::string> 
    142                                 (m->get_body_lines()); 
     143                                (m->get_entity()->get_body_lines()); 
    143144                else if (hn == "bytes" || hn == ":bytes") 
    144145                        s = boost::lexical_cast<std::string> 
    145                                 (m->get_size() + 
     146                                (m->get_entity()->get_size() + 
    146147                                 m->get_xref_field(true).length() + 2); 
    147148                else 
    148                         s = m->get_field(hname, false); 
     149                        s = m->get_entity()->get_field(hname, false); 
    149150                over_output_header(os, s); 
    150151                c.send_line(os.str()); 
  • nntp/last.cc

    r868b365 r1a970cd  
    11/*  This file is part of Alue, the multiprotocol Internet discussion daemon 
    22 
    3     Copyright © 2009 Antti-Juhani Kaijanaho 
     3    Copyright © 2009, 2010 Antti-Juhani Kaijanaho 
    44 
    55    Alue is free software: you can redistribute it and/or modify it 
     
    2121 
    2222#include "../db/group.hh" 
    23 #include "../msg/msg.hh" 
     23#include "../db/msg.hh" 
    2424 
    2525namespace nntp 
  • nntp/next.cc

    r868b365 r1a970cd  
    11/*  This file is part of Alue, the multiprotocol Internet discussion daemon 
    22 
    3     Copyright © 2009 Antti-Juhani Kaijanaho 
     3    Copyright © 2009, 2010 Antti-Juhani Kaijanaho 
    44 
    55    Alue is free software: you can redistribute it and/or modify it 
     
    2121 
    2222#include "../db/group.hh" 
    23 #include "../msg/msg.hh" 
     23#include "../db/msg.hh" 
    2424 
    2525namespace nntp 
  • nntp/over.cc

    r71e633d r1a970cd  
    2323 
    2424#include "../db/db.hh" 
    25 #include "../msg/msg.hh" 
     25#include "../db/msg.hh" 
     26#include "../msg/entity.hh" 
    2627 
    2728namespace nntp 
     
    4647                void write_article_line(connection::cb, 
    4748                                        db::group::number, 
    48                                         boost::shared_ptr<msg::msg> m) const; 
     49                                        boost::shared_ptr<db::msg> m) const; 
    4950 
    5051                cmd_type cmd; 
     
    6869                        if (args[0][0] == '<') 
    6970                        { 
    70                                 boost::shared_ptr<msg::msg> m; 
     71                                boost::shared_ptr<db::msg> m; 
    7172                                try 
    7273                                { 
     
    133134        void over::write_article_line(connection::cb c, 
    134135                                      db::group::number artnum, 
    135                                       boost::shared_ptr<msg::msg> m) 
     136                                      boost::shared_ptr<db::msg> m) 
    136137                const 
    137138        { 
     
    151152                                if (full) s = hname + ": "; 
    152153                                s += boost::lexical_cast<std::string> 
    153                                         (m->get_body_lines()); 
     154                                        (m->get_entity()->get_body_lines()); 
    154155                        } 
    155156                        else if (hn == "bytes" || hn == ":bytes") 
     
    157158                                if (full) s = hname + ": "; 
    158159                                s += boost::lexical_cast<std::string> 
    159                                         (m->get_size()); 
     160                                        (m->get_entity()->get_size()); 
    160161                        } 
    161162                        else 
    162                                 s = m->get_field(hname, full); 
     163                                s = m->get_entity()->get_field(hname, full); 
    163164 
    164165                        over_output_header(os, s); 
  • nntp/post.cc

    r4c34ee2 r1a970cd  
    2121 
    2222#include "../db/db.hh" 
     23#include "../db/msg.hh" 
    2324#include "../logger/logline.hh" 
    24 #include "../msg/msg.hh" 
     25#include "../msg/entity.hh" 
     26#include "../msg/util.hh" 
    2527 
    2628namespace 
     
    3739        connection::continuation::ptr read_handler::operator()(std::string data) 
    3840        { 
    39                 boost::shared_ptr<msg::msg> m; 
     41                db::msg::ptr m; 
    4042                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()); 
    4347                } catch (std::exception &e) { 
    4448                        std::ostringstream ss; 
  • smtp_client/smtp_client.cc

    rae733bf r1a970cd  
    2222#include "../config.hh" 
    2323#include "../logger/logline.hh" 
    24 #include "../msg/msg.hh" 
     24#include "../msg/entity.hh" 
     25#include "../msg/util.hh" 
     26#include "../util.hh" 
    2527 
    2628#include <boost/algorithm/string/case_conv.hpp> 
     
    3739        { 
    3840                message = msg::crlf_canonize(message); 
    39                 boost::shared_ptr<msg::msg> msg 
    40                         (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); 
    4345                message = msg::dot_stuff(msg->get_entity()); 
    4446 
  • tlate/date_value.cc

    rc04e3c7 r1a970cd  
    3030#include "../msg/lexutils.hh" 
    3131#include "../msg/mime_entity.hh" 
    32 #include "../msg/msg.hh" 
    3332#include "../uri.hh" 
    3433 
  • tlate/msg_value.cc

    re7bbf3c r1a970cd  
    2828 
    2929#include "../db/threaded.hh" 
     30#include "../db/msg.hh" 
    3031#include "../html/util.hh" 
    3132#include "../http/compose.hh" 
     33#include "../msg/entity.hh" 
    3234#include "../msg/lexutils.hh" 
    3335#include "../msg/mime_entity.hh" 
    34 #include "../msg/msg.hh" 
    3536#include "../uri.hh" 
    3637 
     
    4445        class xref_seq : public sequential_value 
    4546        { 
    46                 msg::msg::const_ptr m; 
     47                db::msg::const_ptr m; 
    4748                db::user::const_ptr u; 
    4849 
    4950                class vit : public virtual_iterator 
    5051                { 
    51                         msg::msg::xref_type::const_iterator it; 
     52                        db::msg::xref_type::const_iterator it; 
    5253                        mutable value::const_ptr cur; 
    5354                        db::user::const_ptr u; 
    5455  
    55                         vit(msg::msg::xref_type::const_iterator it, 
     56                        vit(db::msg::xref_type::const_iterator it, 
    5657                            value::const_ptr cur, 
    5758                            db::user::const_ptr u) 
     
    6162                                {} 
    6263               public: 
    63                         vit(msg::msg::xref_type::const_iterator it, 
     64                        vit(db::msg::xref_type::const_iterator it, 
    6465                            db::user::const_ptr u) 
    6566                                : it(it) 
     
    8586 
    8687        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) 
    8889                        : m(m) 
    8990                        , u(u) 
     
    130131                using html::quote; 
    131132                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(); 
    133135                std::string msgid = tn->get_msgid(); 
    134136                bool rauthz = m ? m->reading_authz(u) : false; 
     
    157159                else if (rauthz && m && var == "from") 
    158160                        rv.reset(new sv(quote(decode_unstructured 
    159                                               (m->get_field("From", false)), 
     161                                              (e->get_field("From", false)), 
    160162                                              !authn))); 
    161163                else if (rauthz && m && var == "subject") 
    162164                        rv.reset(new sv(quote(decode_unstructured 
    163                                               (m->get_field("Subject", false)), 
     165                                              (e->get_field("Subject", false)), 
    164166                                              !authn))); 
    165167                else if (rauthz && m && var == "date") 
    166                         rv.reset(new date_value(m->parsed_date())); 
     168                        rv.reset(new date_value(e->parsed_date())); 
    167169                else if (rauthz && var == "latest-date" && 
    168170                         !tn->get_latest_date().is_special()) 
     
    170172                                                 
    171173                else if (rauthz && m && var == "header") 
    172                         rv.reset(new header_value(m,!u)); 
     174                        rv.reset(new header_value(e,!u)); 
    173175                else if (rauthz && m && var == "body") 
    174176                { 
    175                         msg::mime_entity::const_ptr me = m->get_mime_entity(); 
     177                        msg::mime_entity::const_ptr me = e->get_mime_entity(); 
    176178                        rv = me->get_tlate_value(authn); 
    177179                }