X-Git-Url: http://gitweb/?a=blobdiff_plain;f=pkgadd.cc;h=2310ea05ede54e09e61bcb8637d9b44527939fc9;hb=d1c46e97eef9cc1a8fd01a32d36315c8d2286c35;hp=dbc564157e28f3a68c1140f40ed883a83d12cc91;hpb=9ac667e68d3e36eb99272eac57219002ee2318e6;p=pkgutils-cross.git

diff --git a/pkgadd.cc b/pkgadd.cc
index dbc5641..2310ea0 100644
--- a/pkgadd.cc
+++ b/pkgadd.cc
@@ -2,7 +2,10 @@
 //  pkgutils
 // 
 //  Copyright (c) 2000-2005 Per Liden
-// 
+//  Copyright (c) 2006-2013 by CRUX team (http://crux.nu)
+//
+//  Patches for alternative pkgadd.conf file by Jose V Beneyto <sepen@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
 //  the Free Software Foundation; either version 2 of the License, or
@@ -32,6 +35,7 @@ void pkgadd::run(int argc, char** argv)
 	// Check command line options
 	//
 	string o_root;
+	string o_config;
 	string o_package;
 	bool o_upgrade = false;
 	bool o_force = false;
@@ -42,6 +46,10 @@ void pkgadd::run(int argc, char** argv)
 			assert_argument(argv, argc, i);
 			o_root = argv[i + 1];
 			i++;
+		} else if (option == "-c" || option == "--config") {
+			assert_argument(argv, argc, i);
+			o_config = argv[i + 1];
+			i++;
 		} else if (option == "-u" || option == "--upgrade") {
 			o_upgrade = true;
 		} else if (option == "-f" || option == "--force") {
@@ -70,7 +78,7 @@ void pkgadd::run(int argc, char** argv)
 		db_open(o_root);
 
 		pair<string, pkginfo_t> package = pkg_open(o_package);
-		vector<rule_t> config_rules = read_config();
+		vector<rule_t> config_rules = read_config(o_config);
 
 		bool installed = db_find_pkg(package.first);
 		if (installed && !o_upgrade)
@@ -78,6 +86,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 +110,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();
 	}
 }
@@ -110,18 +119,21 @@ void pkgadd::print_help() const
 {
 	cout << "usage: " << utilname << " [options] <file>" << endl
 	     << "options:" << endl
-	     << "  -u, --upgrade       upgrade package with the same name" << endl
-	     << "  -f, --force         force install, overwrite conflicting files" << endl
-	     << "  -r, --root <path>   specify alternative installation root" << endl
-	     << "  -v, --version       print version and exit" << endl
-	     << "  -h, --help          print help and exit" << endl;
+	     << "  -u, --upgrade        upgrade package with the same name" << endl
+	     << "  -f, --force          force install, overwrite conflicting files" << endl
+	     << "  -r, --root <path>    specify alternative installation root" << endl
+	     << "  -c, --config <file>  use alternate configuration file" << endl
+	     << "  -v, --version        print version and exit" << endl
+	     << "  -h, --help           print help and exit" << endl;
 }
 
-vector<rule_t> pkgadd::read_config() const
+vector<rule_t> pkgadd::read_config(string file) const
 {
 	vector<rule_t> rules;
 	unsigned int linecount = 0;
-	const string filename = root + PKGADD_CONF;
+	string filename = root + PKGADD_CONF;
+
+	if (!file.empty()) filename = file;
 	ifstream in(filename.c_str());
 
 	if (in) {
@@ -140,9 +152,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 +187,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 +212,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;
+}