CRUX-ARM : Home

Home :: Documentation :: Download :: Development :: Community :: Ports :: Packages :: Bugs :: Links :: About :: Donors
Bug #336: Only accept http/https/ftp/file protocols in sources.
[pkgutils-cross.git] / pkgadd.cc
index dbc564157e28f3a68c1140f40ed883a83d12cc91..4bc16520aea2b166627f549318af5ef66939909b 100644 (file)
--- a/pkgadd.cc
+++ b/pkgadd.cc
@@ -2,6 +2,7 @@
 //  pkgutils
 // 
 //  Copyright (c) 2000-2005 Per Liden
+//  Copyright (c) 2006-2007 by CRUX team (http://crux.nu)
 // 
 //  This program is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -78,6 +79,7 @@ void pkgadd::run(int argc, char** argv)
                else if (!installed && o_upgrade)
                        throw runtime_error("package " + package.first + " not previously installed (skip -u to install)");
       
+               set<string> non_install_files = apply_install_rules(package.first, package.second, config_rules);
                set<string> conflicting_files = db_find_conflicts(package.first, package.second);
       
                if (!conflicting_files.empty()) {
@@ -101,7 +103,7 @@ void pkgadd::run(int argc, char** argv)
    
                db_add_pkg(package.first, package.second);
                db_commit();
-               pkg_install(o_package, keep_list);
+               pkg_install(o_package, keep_list, non_install_files);
                ldconfig();
        }
 }
@@ -140,9 +142,9 @@ vector<rule_t> pkgadd::read_config() const
                                if (sscanf(line.c_str(), "%s %s %s %s", event, pattern, action, dummy) != 3)
                                        throw runtime_error(filename + ":" + itos(linecount) + ": wrong number of arguments, aborting");
 
-                               if (!strcmp(event, "UPGRADE")) {
+                               if (!strcmp(event, "UPGRADE") || !strcmp(event, "INSTALL")) {
                                        rule_t rule;
-                                       rule.event = rule_t::UPGRADE;
+                                       rule.event = strcmp(event, "UPGRADE") ? INSTALL : UPGRADE;
                                        rule.pattern = pattern;
                                        if (!strcmp(action, "YES")) {
                                                rule.action = true;
@@ -175,21 +177,17 @@ vector<rule_t> pkgadd::read_config() const
 set<string> pkgadd::make_keep_list(const set<string>& files, const vector<rule_t>& rules) const
 {
        set<string> keep_list;
+       vector<rule_t> found;
+
+       find_rules(rules, UPGRADE, found);
 
        for (set<string>::const_iterator i = files.begin(); i != files.end(); i++) {
-               for (vector<rule_t>::const_reverse_iterator j = rules.rbegin(); j != rules.rend(); j++) {
-                       if ((*j).event == rule_t::UPGRADE) {
-                               regex_t preg;
-                               if (regcomp(&preg, (*j).pattern.c_str(), REG_EXTENDED | REG_NOSUB))
-                                       throw runtime_error("error compiling regular expression '" + (*j).pattern + "', aborting");
-
-                               if (!regexec(&preg, (*i).c_str(), 0, 0, 0)) {
-                                       if (!(*j).action)
-                                               keep_list.insert(keep_list.end(), *i);
-                                       regfree(&preg);
-                                       break;
-                               }
-                               regfree(&preg);
+               for (vector<rule_t>::reverse_iterator j = found.rbegin(); j != found.rend(); j++) {
+                       if (rule_applies_to_file(*j, *i)) {
+                               if (!(*j).action)
+                                       keep_list.insert(keep_list.end(), *i);
+
+                               break;
                        }
                }
        }
@@ -204,3 +202,69 @@ set<string> pkgadd::make_keep_list(const set<string>& files, const vector<rule_t
 
        return keep_list;
 }
+
+set<string> pkgadd::apply_install_rules(const string& name, pkginfo_t& info, const vector<rule_t>& rules)
+{
+       // TODO: better algo(?)
+       set<string> install_set;
+       set<string> non_install_set;
+       vector<rule_t> found;
+
+       find_rules(rules, INSTALL, found);
+
+       for (set<string>::const_iterator i = info.files.begin(); i != info.files.end(); i++) {
+               bool install_file = true;
+
+               for (vector<rule_t>::reverse_iterator j = found.rbegin(); j != found.rend(); j++) {
+                       if (rule_applies_to_file(*j, *i)) {
+                               install_file = (*j).action;
+                               break;
+                       }
+               }
+
+               if (install_file)
+                       install_set.insert(install_set.end(), *i);
+               else
+                       non_install_set.insert(*i);
+       }
+
+       info.files.clear();
+       info.files = install_set;
+
+#ifndef NDEBUG
+       cerr << "Install set:" << endl;
+       for (set<string>::iterator j = info.files.begin(); j != info.files.end(); j++) {
+               cerr << "   " << (*j) << endl;
+       }
+       cerr << endl;
+
+       cerr << "Non-Install set:" << endl;
+       for (set<string>::iterator j = non_install_set.begin(); j != non_install_set.end(); j++) {
+               cerr << "   " << (*j) << endl;
+       }
+       cerr << endl;
+#endif
+
+       return non_install_set;
+}
+
+void pkgadd::find_rules(const vector<rule_t>& rules, rule_event_t event, vector<rule_t>& found) const
+{
+       for (vector<rule_t>::const_iterator i = rules.begin(); i != rules.end(); i++)
+               if (i->event == event)
+                       found.push_back(*i);
+}
+
+bool pkgadd::rule_applies_to_file(const rule_t& rule, const string& file) const
+{
+       regex_t preg;
+       bool ret;
+
+       if (regcomp(&preg, rule.pattern.c_str(), REG_EXTENDED | REG_NOSUB))
+               throw runtime_error("error compiling regular expression '" + rule.pattern + "', aborting");
+
+       ret = !regexec(&preg, file.c_str(), 0, 0, 0);
+       regfree(&preg);
+
+       return ret;
+}