<pre style='margin:0'>
Mihai Moldovan (Ionic) pushed a commit to branch master
in repository macports-base.
</pre>
<p><a href="https://github.com/macports/macports-base/commit/ba8e3a66f9300d66fe30474dc69043f2d7ba6717">https://github.com/macports/macports-base/commit/ba8e3a66f9300d66fe30474dc69043f2d7ba6717</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit ba8e3a66f9300d66fe30474dc69043f2d7ba6717
</span>Author: Mihai Moldovan <ionic@ionic.de>
AuthorDate: Thu Feb 16 08:58:32 2017 +0100
<span style='display:block; white-space:pre;color:#404040;'> misc: let 'port provides' and trace mode honor the FS case-sensitivity.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Extend Pextlib with functions to fetch the file system case-sensitivity
</span><span style='display:block; white-space:pre;color:#404040;'> value for a specific path. The TCL interface than uses this function
</span><span style='display:block; white-space:pre;color:#404040;'> when mapping a file path to a port name is requested.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> cregistry and registry2.0 were updated to perform lookups of paths to
</span><span style='display:block; white-space:pre;color:#404040;'> port IDs or names case-insensitively if requested by using the "COLLATE
</span><span style='display:block; white-space:pre;color:#404040;'> NOCASE" option.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> For this to actually work in a timely manner, a new "COLLATE NOCASE"
</span><span style='display:block; white-space:pre;color:#404040;'> index is needed for the actual_path column. Thus bumping the internal DB
</span><span style='display:block; white-space:pre;color:#404040;'> version number.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This fixes bugs where port build systems access files on
</span><span style='display:block; white-space:pre;color:#404040;'> case-insensitive file systems with different capitalization than
</span><span style='display:block; white-space:pre;color:#404040;'> registered in our database - thus bypassing trace mode's sanity checks
</span><span style='display:block; white-space:pre;color:#404040;'> as the files in question are "unknown".
</span>---
src/cregistry/entry.c | 43 +++++++-
src/cregistry/entry.h | 6 +-
src/cregistry/sql.c | 35 ++++++-
src/pextlib1.0/Pextlib.c | 200 ++++++++++++++++++++++++++++++++++++-
src/pextlib1.0/Pextlib.h | 8 +-
src/pextlib1.0/tracelib.c | 21 +++-
src/registry2.0/entry.c | 20 +++-
src/registry2.0/receipt_flat.tcl | 7 +-
src/registry2.0/receipt_sqlite.tcl | 6 +-
src/registry2.0/registry.tcl | 10 +-
10 files changed, 332 insertions(+), 24 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/entry.c b/src/cregistry/entry.c
</span><span style='display:block; white-space:pre;color:#808080;'>index c056d66..9dfc782 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/entry.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/entry.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,7 +1,7 @@
</span> /*
* entry.c
*
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2010-2011, 2014 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2010-2011, 2014, 2017 The MacPorts Project
</span> * Copyright (c) 2007 Chris Pickel <sfiera@macports.org>
* All rights reserved.
*
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -39,6 +39,7 @@
</span> #include <sqlite3.h>
#include <stdlib.h>
#include <string.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</span>
/*
* TODO: possibly, allow reg_entry_search to take different matching strategies
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -517,16 +518,31 @@ int reg_entry_installed(reg_registry* reg, char* name, reg_entry*** entries,
</span> *
* @param [in] reg registry to search in
* @param [in] path path of the file to check ownership of
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] cs false if check should be performed case-insensitive,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * true otherwise
</span> * @param [out] entry the owner, or NULL if no active port owns the file
* @param [out] errPtr on error, a description of the error that occurred
* @return true if success; false if failure
*/
<span style='display:block; white-space:pre;background:#ffe0e0;'>-int reg_entry_owner(reg_registry* reg, char* path, reg_entry** entry,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int reg_entry_owner(reg_registry* reg, char* path, int cs, reg_entry** entry,
</span> reg_error* errPtr) {
int result = 0;
sqlite3_stmt* stmt = NULL;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- char* query = "SELECT id FROM registry.files WHERE actual_path=? AND active";
</span> int lower_bound = 0;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Make sure query_template is as big as the buffer might get. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const char* query_template = "SELECT id FROM registry.files WHERE (actual_path = ? COLLATE NOCASE) AND active";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const int query_max_size = strlen(query_template) + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char* query = malloc(query_max_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!query) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ snprintf(query, query_max_size, "SELECT id FROM registry.files WHERE (actual_path = ? %s) AND active",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cs ? "" : "COLLATE NOCASE");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if ((sqlite3_prepare_v2(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
&& (sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC)
== SQLITE_OK)) {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -555,6 +571,7 @@ int reg_entry_owner(reg_registry* reg, char* path, reg_entry** entry,
</span> if (stmt) {
sqlite3_finalize(stmt);
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(query);
</span> return result;
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -568,12 +585,27 @@ int reg_entry_owner(reg_registry* reg, char* path, reg_entry** entry,
</span> *
* @param [in] reg registry to find file in
* @param [in] path path of file to get owner of
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] cs false if check should be performed case-insensitive,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * true otherwise
</span> * @return id of owner, or 0 for none
*/
<span style='display:block; white-space:pre;background:#ffe0e0;'>-sqlite_int64 reg_entry_owner_id(reg_registry* reg, char* path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+sqlite_int64 reg_entry_owner_id(reg_registry* reg, char* path, int cs) {
</span> sqlite3_stmt* stmt = NULL;
sqlite_int64 result = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- char* query = "SELECT id FROM registry.files WHERE actual_path=? AND active";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Make sure query_template is as big as the buffer might get. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const char* query_template = "SELECT id FROM registry.files WHERE (actual_path = ? COLLATE NOCASE) AND active";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const int query_max_size = strlen(query_template) + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char* query = malloc(query_max_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!query) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ snprintf(query, query_max_size, "SELECT id FROM registry.files WHERE (actual_path = ? %s) AND active",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cs ? "" : "COLLATE NOCASE");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if ((sqlite3_prepare_v2(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
&& (sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC)
== SQLITE_OK)) {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -588,6 +620,7 @@ sqlite_int64 reg_entry_owner_id(reg_registry* reg, char* path) {
</span> if (stmt) {
sqlite3_finalize(stmt);
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(query);
</span> return result;
}
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/entry.h b/src/cregistry/entry.h
</span><span style='display:block; white-space:pre;color:#808080;'>index a412ed3..67bbf5f 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/entry.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/entry.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -61,9 +61,9 @@ int reg_entry_imaged(reg_registry* reg, const char* name, const char* version,
</span> int reg_entry_installed(reg_registry* reg, char* name, reg_entry*** entries,
reg_error* errPtr);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-sqlite_int64 reg_entry_owner_id(reg_registry* reg, char* path);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-int reg_entry_owner(reg_registry* reg, char* path, reg_entry** entry,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- reg_error* errPtr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+sqlite_int64 reg_entry_owner_id(reg_registry* reg, char* path, int cs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int reg_entry_owner(reg_registry* reg, char* path, int cs,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ reg_entry** entry, reg_error* errPtr);
</span>
int reg_entry_propget(reg_entry* entry, char* key, char** value,
reg_error* errPtr);
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/sql.c b/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 59b7e9d..8fa681b 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2,7 +2,7 @@
</span> * sql.c
*
* Copyright (c) 2007 Chris Pickel <sfiera@macports.org>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2012, 2014 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2012, 2014, 2017 The MacPorts Project
</span> * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -134,7 +134,7 @@ int create_tables(sqlite3* db, reg_error* errPtr) {
</span>
/* metadata table */
"CREATE TABLE registry.metadata (key UNIQUE, value)",
<span style='display:block; white-space:pre;background:#ffe0e0;'>- "INSERT INTO registry.metadata (key, value) VALUES ('version', '1.202')",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "INSERT INTO registry.metadata (key, value) VALUES ('version', '1.203')",
</span> "INSERT INTO registry.metadata (key, value) VALUES ('created', strftime('%s', 'now'))",
/* ports table */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -172,6 +172,7 @@ int create_tables(sqlite3* db, reg_error* errPtr) {
</span> "CREATE INDEX registry.file_port ON files(id)",
"CREATE INDEX registry.file_path ON files(path)",
"CREATE INDEX registry.file_actual ON files(actual_path)",
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ "CREATE INDEX registry.file_actual_nocase ON files(actual_path COLLATE NOCASE)",
</span>
/* dependency map */
"CREATE TABLE registry.dependencies ("
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -587,6 +588,34 @@ int update_db(sqlite3* db, reg_error* errPtr) {
</span> continue;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (sql_version(NULL, -1, version, -1, "1.203") < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * A new index on files.actual_path with the COLLATE NOCASE attribute
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * will speed up queries with the equality operator and the COLLATE NOCASE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * attribute or the LIKE operator. Needed for file mapping to ports
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * on case-insensitive file systems. Without it, any search operation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * will be very, very, very slow.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static char* version_1_203_queries[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "CREATE INDEX registry.file_actual_nocase ON files(actual_path COLLATE NOCASE)",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Update version and commit */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "UPDATE registry.metadata SET value = '1.203' WHERE key = 'version'",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "COMMIT",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sqlite3_finalize(stmt);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ stmt = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!do_queries(db, version_1_203_queries, errPtr)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rollback_db(db);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ did_update = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* add new versions here, but remember to:
* - finalize the version query statement and set stmt to NULL
* - do _not_ use "BEGIN" in your query list, since a transaction has
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -596,7 +625,7 @@ int update_db(sqlite3* db, reg_error* errPtr) {
</span> * - update the current version number below
*/
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (sql_version(NULL, -1, version, -1, "1.202") > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (sql_version(NULL, -1, version, -1, "1.203") > 0) {
</span> /* the registry was already upgraded to a newer version and cannot be used anymore */
reg_throw(errPtr, REG_INVALID, "Version number in metadata table is newer than expected.");
sqlite3_finalize(stmt);
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/Pextlib.c b/src/pextlib1.0/Pextlib.c
</span><span style='display:block; white-space:pre;color:#808080;'>index d5c7699..0a125cf 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/Pextlib.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/Pextlib.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4,7 +4,7 @@
</span> * Copyright (c) 2002 - 2003 Apple Inc.
* Copyright (c) 2004 - 2005 Paul Guyot <pguyot@kallisys.net>
* Copyright (c) 2004 Landon Fuller <landonf@macports.org>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2007 - 2016 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2007 - 2017 The MacPorts Project
</span> * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -52,6 +52,7 @@
</span> #include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/param.h>
</span> #include <ctype.h>
#include <errno.h>
#include <fcntl.h>
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -648,6 +649,201 @@ int SetMaxOpenFilesCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int obj
</span> return TCL_OK;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/attr.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/mount.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct volcaps {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ u_int32_t size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ vol_capabilities_attr_t volcaps;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} volcaps_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Default function for determining the FS case sensitivity on Darwin.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Using getattrlist().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int fs_case_sensitive_darwin(const char *path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* TODO: cache mount point CS value. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct statfs f = { 0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct attrlist attrlist = { 0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ volcaps_t volcaps = { 0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == statfs(path, &f)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ attrlist.volattr = ATTR_VOL_CAPABILITIES;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == getattrlist(f.f_mntonname, &attrlist, &volcaps, sizeof(volcaps), 0)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((attrlist.volattr & ATTR_VOL_CAPABILITIES) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((volcaps.volcaps.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_CASE_SENSITIVE)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* capabilities bit for case-sensitivity valid */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = (volcaps.volcaps.capabilities[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_CASE_SENSITIVE) != 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Fallback function to determine FS case sensitivity.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * lstat()'s the given path, its lowercase and uppercase versions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * If all three versions exist and are the same file (as determined
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * by their inode numbers), then the FS is case-insensitive and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 0 is returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Otherwise, the FS is case-sensitive and 1 is returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * In case of errors (e.g., if the original file does not exist),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * -1 is returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int fs_case_sensitive_fallback(const char *path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* TODO: fetch mount point and cache mount point CS value. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *lowercase_path = strdup(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *uppercase_path = strdup(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((!lowercase_path) || (!uppercase_path)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(lowercase_path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(uppercase_path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ for (char *tmp_ptr_low = lowercase_path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *tmp_ptr_up = uppercase_path;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *tmp_ptr_low && *tmp_ptr_up; /* Since both are copies of the same string,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ should be the same anyway. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ++tmp_ptr_low, ++tmp_ptr_up) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *tmp_ptr_low = tolower(*tmp_ptr_low);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *tmp_ptr_up = toupper(*tmp_ptr_up);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct stat path_stat = { 0 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lowercase_path_stat = { 0 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uppercase_path_stat = { 0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == lstat(path, &path_stat)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(lowercase_path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(uppercase_path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((0 == strcmp(path, lowercase_path)) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (0 == strcmp(path, uppercase_path))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * All three strings are equal. We can't check for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * FS case-sensitivity in this case.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * And it doesn't matter either way!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == lstat(lowercase_path, &lowercase_path_stat)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Lowercased version doesn't exist, CS. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (-1 == lstat(uppercase_path, &uppercase_path_stat)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Uppercased version doesn't exist, CS. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * All three files exists, but we must make sure they
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * are really the same file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (path_stat.st_ino == lowercase_path_stat.st_ino) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Lowercase and original path files are the same,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * but that's not too surprising since most passed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * values will already be in lowercased form.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Also check the uppercase variant.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The special case that all three versions are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * actually the same (can happen if a path consists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * of case-agnostic Unicode characters only) is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * already handled above.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (path_stat.st_ino == uppercase_path_stat.st_ino) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Truly case-insensitive! */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Bummer, lowercased version matches the original
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * file's inode number, but the uppercased one
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * doesn't. CS.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Just similar-named, still a case-sensitive FS. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(lowercase_path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(uppercase_path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Determines FS case-sensitivity for a specific path.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Returns 1 if the FS is case-sensitive, 0 otherwise.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Errors out if the case-sensitivity could not be determined.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int FSCaseSensitiveCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Tcl_Obj *tcl_result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (objc != 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Tcl_WrongNumArgs(interp, 1, objv, "path");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *path = Tcl_GetString(objv[1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = fs_case_sensitive_darwin(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == ret) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = fs_case_sensitive_fallback(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == ret) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Tcl_SetResult(interp, "unable to determine FS case-sensitivity", TCL_STATIC);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tcl_result = Tcl_NewBooleanObj(ret);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Tcl_SetObjResult(interp, tcl_result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> int Pextlib_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.4", 0) == NULL)
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -710,6 +906,8 @@ int Pextlib_Init(Tcl_Interp *interp)
</span> Tcl_CreateObjCommand(interp, "check_broken_dns", CheckBrokenDNSCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "set_max_open_files", SetMaxOpenFilesCmd, NULL, NULL);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ Tcl_CreateObjCommand(interp, "fs_case_sensitive", FSCaseSensitiveCmd, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if (Tcl_PkgProvide(interp, "Pextlib", "1.0") != TCL_OK)
return TCL_ERROR;
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/Pextlib.h b/src/pextlib1.0/Pextlib.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 4ab4fb3..aaee1fa 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/Pextlib.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/Pextlib.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,7 +1,7 @@
</span> /*
* Pextlib.h
*
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2009 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2009, 2017 The MacPorts Project
</span> * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -35,3 +35,9 @@ void ui_msg(Tcl_Interp *interp, const char *format, ...) __attribute__((format(p
</span> void ui_notice(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3)));
void ui_info(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3)));
void ui_debug(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3)));
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int fs_case_sensitive_darwin(const char *path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int fs_case_sensitive_fallback(const char *path);
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/tracelib.c b/src/pextlib1.0/tracelib.c
</span><span style='display:block; white-space:pre;color:#808080;'>index f27acbb..cb9c146 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/tracelib.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/tracelib.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4,7 +4,7 @@
</span> * tracelib.c
*
* Copyright (c) 2007-2008 Eugene Pimenov (GSoC)
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2008-2010, 2012-2015 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2008-2010, 2012-2015, 2017 The MacPorts Project
</span> * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -604,6 +604,7 @@ static void sandbox_violation(int sock UNUSED, const char *path, sandbox_violati
</span> static void dep_check(int sock, char *path) {
char *port = 0;
char *t;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ int fs_cs = -1;
</span> reg_registry *reg;
reg_entry entry;
reg_error error;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -614,10 +615,26 @@ static void dep_check(int sock, char *path) {
</span> answer(sock, "#");
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fs_cs = fs_case_sensitive_darwin(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == fs_cs) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fs_cs = fs_case_sensitive_fallback(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == fs_cs) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Unable to determine FS case-sensitivity.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Assume the worst case (case-insensitive.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fs_cs = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* find the port id */
entry.reg = reg;
entry.proc = NULL;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- entry.id = reg_entry_owner_id(reg, path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ entry.id = reg_entry_owner_id(reg, path, fs_cs);
</span> if (entry.id == 0) {
/* file isn't known to MacPorts */
answer(sock, "?");
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/entry.c b/src/registry2.0/entry.c
</span><span style='display:block; white-space:pre;color:#808080;'>index f13d3b9..0647816 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/entry.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/entry.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -437,22 +437,32 @@ static int entry_installed(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]){
</span>
/*
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * registry::entry owner filename
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * registry::entry owner filename [cs = true]
</span> *
* Returns the port that owns the given filename (empty string if none).
*/
static int entry_owner(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
reg_registry* reg = registry_for(interp, reg_attached);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (objc != 3) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Tcl_WrongNumArgs(interp, 2, objv, "path");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int cs = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((objc < 3) || (objc > 4)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Tcl_WrongNumArgs(interp, 2, objv, "path ?cs?");
</span> return TCL_ERROR;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (objc == 4) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (Tcl_GetBooleanFromObj(interp, objv[3], &cs) != TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (reg == NULL) {
</span> return TCL_ERROR;
} else {
char* path = Tcl_GetString(objv[2]);
reg_entry* entry;
reg_error error;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (reg_entry_owner(reg, path, &entry, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (reg_entry_owner(reg, path, cs, &entry, &error)) {
</span> if (entry == NULL) {
return TCL_OK;
} else {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/receipt_flat.tcl b/src/registry2.0/receipt_flat.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 85c8254..4c488e9 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/receipt_flat.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/receipt_flat.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -600,13 +600,18 @@ proc open_file_map {{readonly 0}} {
</span> # open the file map if required.
#
# - file the file to test
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# - cs boolean value indicating a case-sensitive search
</span> # return the 0 if the file is not registered, the name of the port otherwise.
#
<span style='display:block; white-space:pre;background:#ffe0e0;'>-proc file_registered {file} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc file_registered {file cs} {
</span> variable file_map
open_file_map 1
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$cs} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_warn "Case-sensitive search not implemented."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if {[::filemap exists file_map $file]} {
return [::filemap get file_map $file]
} else {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/receipt_sqlite.tcl b/src/registry2.0/receipt_sqlite.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index b6797c1..7adc2cb 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/receipt_sqlite.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/receipt_sqlite.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -123,10 +123,12 @@ proc entry_exists_for_name {name} {
</span> #
# @param file
# The full path to the file to be tested.
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param cs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Boolean value indicating a case-sensitive check.
</span> # @return 0 if the file is not registered to any port. The name of the port
# otherwise.
<span style='display:block; white-space:pre;background:#ffe0e0;'>-proc file_registered {file} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- set port [registry::entry owner $file]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc file_registered {file cs} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set port [registry::entry owner $file $cs]
</span> if {$port ne ""} {
return [$port name]
} else {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/registry.tcl b/src/registry2.0/registry.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 6da2448..0bfb2bd 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/registry.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/registry.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -38,6 +38,7 @@ package require receipt_sqlite 1.0
</span> package require portimage 2.0
package require registry_uninstall 2.0
package require msgcat
<span style='display:block; white-space:pre;background:#e0ffe0;'>+package require Pextlib 1.0
</span>
namespace eval registry {
variable lockfd
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -236,7 +237,14 @@ proc open_file_map {args} {
</span>
proc file_registered {file} {
global macports::registry.format
<span style='display:block; white-space:pre;background:#ffe0e0;'>- return [${macports::registry.format}::file_registered $file]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set cs false
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[catch {fs_case_sensitive $file} cs]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_debug "Unable to get file system case-sensitivity of file $file, assuming worst case (case-insensitive.)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set cs false
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return [${macports::registry.format}::file_registered $file $cs]
</span> }
proc port_registered {name} {
</pre><pre style='margin:0'>
</pre>