[81150] trunk/dports/fuse/sshfs
dports at macports.org
dports at macports.org
Mon Jul 25 19:35:28 PDT 2011
Revision: 81150
http://trac.macports.org/changeset/81150
Author: dports at macports.org
Date: 2011-07-25 19:35:25 -0700 (Mon, 25 Jul 2011)
Log Message:
-----------
sshfs: fuse4x compatibility
* rewrite macfuse dependency to allow fuse4x to satisfy it
* add patch that uses __APPLE__ instead of (__FreeBSD__ >= 10) to
test whether we're on a Mac, and adds a semaphore emulation layer
if we're using Fuse4X (MacFUSE provides one of its own)
Modified Paths:
--------------
trunk/dports/fuse/sshfs/Portfile
Added Paths:
-----------
trunk/dports/fuse/sshfs/files/
trunk/dports/fuse/sshfs/files/patch-fuse4x-compat.diff
Modified: trunk/dports/fuse/sshfs/Portfile
===================================================================
--- trunk/dports/fuse/sshfs/Portfile 2011-07-26 02:20:17 UTC (rev 81149)
+++ trunk/dports/fuse/sshfs/Portfile 2011-07-26 02:35:25 UTC (rev 81150)
@@ -28,7 +28,7 @@
depends_build path:bin/pkg-config:pkgconfig
depends_lib port:gettext \
path:lib/pkgconfig/glib-2.0.pc:glib2 \
- port:macfuse \
+ path:lib/pkgconfig/fuse.pc:macfuse \
port:libiconv \
port:openssh
@@ -37,10 +37,13 @@
platform darwin {
patch_sites http://macfuse.googlecode.com/svn/tags/macfuse-2.0/filesystems/sshfs
- patchfiles sshfs-fuse-${version}-macosx.patch
+ patchfiles sshfs-fuse-${version}-macosx.patch \
+ patch-fuse4x-compat.diff
checksums-append sshfs-fuse-${version}-macosx.patch md5 08330f4c10e25052b3a5c26d180e4752 \
sha1 24e6721c25fb883c945550ac62e20f4c35f4393e
# override patch.pre_args since it defaults to -p0
patch.pre_args -p1
+
+ use_autoreconf yes
}
Added: trunk/dports/fuse/sshfs/files/patch-fuse4x-compat.diff
===================================================================
--- trunk/dports/fuse/sshfs/files/patch-fuse4x-compat.diff (rev 0)
+++ trunk/dports/fuse/sshfs/files/patch-fuse4x-compat.diff 2011-07-26 02:35:25 UTC (rev 81150)
@@ -0,0 +1,625 @@
+diff --git a/Makefile.am b/Makefile.am
+index a80788b..99e1dc8 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -2,14 +2,14 @@
+
+ bin_PROGRAMS = sshfs
+
+-sshfs_SOURCES = sshfs.c cache.c cache.h
++sshfs_SOURCES = sshfs.c cache.c cache.h compat/darwin_semaphore.h compat/darwin_semaphore.c
+ if FUSE_OPT_COMPAT
+ sshfs_SOURCES += compat/fuse_opt.c compat/fuse_opt.h
+ endif
+
+ sshfs_LDADD = $(SSHFS_LIBS)
+ sshfs_CFLAGS = $(SSHFS_CFLAGS)
+-sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\"
++sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\" -Icompat
+
+ EXTRA_DIST = sshnodelay.c FAQ.txt
+ CLEANFILES = sshnodelay.so
+diff --git a/compat/darwin_semaphore.c b/compat/darwin_semaphore.c
+new file mode 100644
+index 0000000..e45fd9a
+--- /dev/null
++++ b/compat/darwin_semaphore.c
+@@ -0,0 +1,229 @@
++/*
++ * Copyright (C) 2000,02 Free Software Foundation, Inc.
++ * This file is part of the GNU C Library.
++ * Written by Ga<EB>l Le Mignot <address at hidden>
++ *
++ * The GNU C Library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The GNU C Library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with the GNU C Library; see the file COPYING.LIB. If not,
++ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#include "darwin_semaphore.h"
++
++#include <assert.h>
++#include <errno.h>
++#include <sys/types.h>
++
++#define __SEM_ID_NONE 0x0
++#define __SEM_ID_LOCAL 0xcafef00d
++
++/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_init.html */
++int
++compat_sem_init(compat_sem_t *sem, int pshared, unsigned int value)
++{
++ if (pshared) {
++ errno = ENOSYS;
++ return -1;
++ }
++
++ sem->id = __SEM_ID_NONE;
++
++ if (pthread_cond_init(&sem->__data.local.count_cond, NULL)) {
++ goto cond_init_fail;
++ }
++
++ if (pthread_mutex_init(&sem->__data.local.count_lock, NULL)) {
++ goto mutex_init_fail;
++ }
++
++ sem->__data.local.count = value;
++ sem->id = __SEM_ID_LOCAL;
++
++ return 0;
++
++mutex_init_fail:
++
++ pthread_cond_destroy(&sem->__data.local.count_cond);
++
++cond_init_fail:
++
++ return -1;
++}
++
++/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_destroy.html */
++int
++compat_sem_destroy(compat_sem_t *sem)
++{
++ int res = 0;
++
++ pthread_mutex_lock(&sem->__data.local.count_lock);
++
++ sem->id = __SEM_ID_NONE;
++ pthread_cond_broadcast(&sem->__data.local.count_cond);
++
++ if (pthread_cond_destroy(&sem->__data.local.count_cond)) {
++ res = -1;
++ }
++
++ pthread_mutex_unlock(&sem->__data.local.count_lock);
++
++ if (pthread_mutex_destroy(&sem->__data.local.count_lock)) {
++ res = -1;
++ }
++
++ return res;
++}
++
++int
++compat_sem_getvalue(compat_sem_t *sem, unsigned int *sval)
++{
++ int res = 0;
++
++ pthread_mutex_lock(&sem->__data.local.count_lock);
++
++ if (sem->id != __SEM_ID_LOCAL) {
++ res = -1;
++ errno = EINVAL;
++ } else {
++ *sval = sem->__data.local.count;
++ }
++
++ pthread_mutex_unlock(&sem->__data.local.count_lock);
++
++ return res;
++}
++
++/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_post.html */
++int
++compat_sem_post(compat_sem_t *sem)
++{
++ int res = 0;
++
++ pthread_mutex_lock(&sem->__data.local.count_lock);
++
++ if (sem->id != __SEM_ID_LOCAL) {
++ res = -1;
++ errno = EINVAL;
++ } else if (sem->__data.local.count < COMPAT_SEM_VALUE_MAX) {
++ sem->__data.local.count++;
++ if (sem->__data.local.count == 1) {
++ pthread_cond_signal(&sem->__data.local.count_cond);
++ }
++ } else {
++ errno = ERANGE;
++ res = -1;
++ }
++
++ pthread_mutex_unlock(&sem->__data.local.count_lock);
++
++ return res;
++}
++
++/* http://www.opengroup.org/onlinepubs/009695399/functions/sem_timedwait.html */
++int
++compat_sem_timedwait(compat_sem_t *sem, const struct timespec *abs_timeout)
++{
++ int res = 0;
++
++ if (abs_timeout &&
++ (abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= 1000000000)) {
++ errno = EINVAL;
++ return -1;
++ }
++
++ pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock,
++ &sem->__data.local.count_lock);
++
++ pthread_mutex_lock(&sem->__data.local.count_lock);
++
++ if (sem->id != __SEM_ID_LOCAL) {
++ errno = EINVAL;
++ res = -1;
++ } else {
++ if (!sem->__data.local.count) {
++ res = pthread_cond_timedwait(&sem->__data.local.count_cond,
++ &sem->__data.local.count_lock,
++ abs_timeout);
++ }
++ if (res) {
++ assert(res == ETIMEDOUT);
++ res = -1;
++ errno = ETIMEDOUT;
++ } else if (sem->id != __SEM_ID_LOCAL) {
++ res = -1;
++ errno = EINVAL;
++ } else {
++ sem->__data.local.count--;
++ }
++ }
++
++ pthread_cleanup_pop(1);
++
++ return res;
++}
++
++/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_trywait.html */
++int
++compat_sem_trywait(compat_sem_t *sem)
++{
++ int res = 0;
++
++ pthread_mutex_lock(&sem->__data.local.count_lock);
++
++ if (sem->id != __SEM_ID_LOCAL) {
++ res = -1;
++ errno = EINVAL;
++ } else if (sem->__data.local.count) {
++ sem->__data.local.count--;
++ } else {
++ res = -1;
++ errno = EAGAIN;
++ }
++
++ pthread_mutex_unlock (&sem->__data.local.count_lock);
++
++ return res;
++}
++
++/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_wait.html */
++int
++compat_sem_wait(compat_sem_t *sem)
++{
++ int res = 0;
++
++ pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock,
++ &sem->__data.local.count_lock);
++
++ pthread_mutex_lock(&sem->__data.local.count_lock);
++
++ if (sem->id != __SEM_ID_LOCAL) {
++ errno = EINVAL;
++ res = -1;
++ } else {
++ while (!sem->__data.local.count) {
++ pthread_cond_wait(&sem->__data.local.count_cond,
++ &sem->__data.local.count_lock);
++ }
++ if (sem->id != __SEM_ID_LOCAL) {
++ res = -1;
++ errno = EINVAL;
++ } else {
++ sem->__data.local.count--;
++ }
++ }
++
++ pthread_cleanup_pop(1);
++
++ return res;
++}
+diff --git a/compat/darwin_semaphore.h b/compat/darwin_semaphore.h
+new file mode 100644
+index 0000000..3f03e41
+--- /dev/null
++++ b/compat/darwin_semaphore.h
+@@ -0,0 +1,69 @@
++/* Copyright (C) 2000,02 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Written by Gaël Le Mignot <address at hidden>
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Library General Public License as
++ published by the Free Software Foundation; either version 2 of the
++ License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Library General Public License for more details.
++
++ You should have received a copy of the GNU Library General Public
++ License along with the GNU C Library; see the file COPYING.LIB. If not,
++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++// This implementation is based on libsem http://lists.debian.org/debian-devel/2004/08/msg00612.html
++
++#ifndef _SEMAPHORE_H_
++#define _SEMAPHORE_H_
++
++/* Caller must not include <semaphore.h> */
++
++#include <pthread.h>
++
++struct __local_sem_t
++{
++ unsigned int count;
++ pthread_mutex_t count_lock;
++ pthread_cond_t count_cond;
++};
++
++typedef struct compat_sem {
++ unsigned int id;
++ union {
++ struct __local_sem_t local;
++ } __data;
++} compat_sem_t;
++
++#define COMPAT_SEM_VALUE_MAX ((int32_t)32767)
++
++int compat_sem_init(compat_sem_t *sem, int pshared, unsigned int value);
++int compat_sem_destroy(compat_sem_t *sem);
++int compat_sem_getvalue(compat_sem_t *sem, unsigned int *value);
++int compat_sem_post(compat_sem_t *sem);
++int compat_sem_timedwait(compat_sem_t *sem, const struct timespec *abs_timeout);
++int compat_sem_trywait(compat_sem_t *sem);
++int compat_sem_wait(compat_sem_t *sem);
++
++
++/* Redefine semaphores. Caller must not include <semaphore.h> */
++
++typedef compat_sem_t sem_t;
++
++#define sem_init(s, p, v) compat_sem_init(s, p, v)
++#define sem_destroy(s) compat_sem_destroy(s)
++#define sem_getvalue(s, v) compat_sem_getvalue(s, v)
++#define sem_post(s) compat_sem_post(s)
++#define sem_timedwait(s, t) compat_sem_timedwait(s, t)
++#define sem_trywait(s) compat_sem_trywait(s)
++#define sem_wait(s) compat_sem_wait(s)
++
++#define SEM_VALUE_MAX COMPAT_SEM_VALUE_MAX
++
++
++#endif /* semaphore.h */
+diff --git a/sshfs.c b/sshfs.c
+index 8a8e858..9220b70 100644
+--- a/sshfs.c.orig 2011-07-23 18:00:48.000000000 -0400
++++ a/sshfs.c 2011-07-23 19:28:43.000000000 -0400
+@@ -19,12 +19,18 @@
+ #include <string.h>
+ #include <stdint.h>
+ #include <errno.h>
+-#if !(__FreeBSD__ >= 10)
+-#include <semaphore.h>
++#ifdef __APPLE__
++/* OS X does not support named semaphores; need some sort of emulation */
++#if (__FreeBSD__ >= 10)
++/* MacFUSE provides a semaphore emulation layer */
++#include <fuse_darwin.h>
+ #else
+-#define MACFUSE_SSHFS_VERSION "2.2.0"
+-#include "fuse_darwin.h"
+-#endif
++/* Fuse4X doesn't; use our own */
++#include "darwin_semaphore.h"
++#endif /* (__FreeBSD__ >= 10) */
++#else
++#include <semaphore.h>
++#endif /* __APPLE__ */
+ #include <pthread.h>
+ #include <netdb.h>
+ #include <signal.h>
+@@ -39,7 +45,7 @@
+ #include <netinet/in.h>
+ #include <netinet/tcp.h>
+ #include <glib.h>
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ #include <libgen.h>
+ #include <strings.h>
+ #endif
+@@ -129,7 +135,7 @@
+
+ #define SSHNODELAY_SO "sshnodelay.so"
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+
+ #ifndef LIBDIR
+ #define LIBDIR "/usr/local/lib"
+@@ -188,7 +194,7 @@
+ int connver;
+ int modifver;
+ int refs;
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ pthread_mutex_t file_lock;
+ #endif
+ };
+@@ -230,7 +236,7 @@
+ int server_version;
+ unsigned remote_uid;
+ unsigned local_uid;
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ unsigned remote_gid;
+ unsigned local_gid;
+ #endif
+@@ -667,7 +673,7 @@
+ }
+ }
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (sshfs.remote_uid_detected) {
+ if (uid == sshfs.remote_uid)
+ uid = sshfs.local_uid;
+@@ -780,7 +786,7 @@
+ #ifdef SSH_NODELAY_WORKAROUND
+ static int do_ssh_nodelay_workaround(void)
+ {
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ char *oldpreload = getenv("DYLD_INSERT_LIBRARIES");
+ #else
+ char *oldpreload = getenv("LD_PRELOAD");
+@@ -789,7 +795,7 @@
+ char sopath[PATH_MAX];
+ int res;
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ char *sshfs_program_path_base = NULL;
+ if (!sshfs_program_path[0]) {
+ goto nobundle;
+@@ -831,7 +837,7 @@
+ return -1;
+ }
+ }
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ pathok:
+ #endif
+
+@@ -840,7 +846,7 @@
+ oldpreload ? " " : "",
+ sopath);
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (!newpreload || setenv("DYLD_INSERT_LIBRARIES", newpreload, 1) == -1)
+ fprintf(stderr, "warning: failed set DYLD_INSERT_LIBRARIES for ssh nodelay workaround\n");
+ #else
+@@ -1541,7 +1547,7 @@
+
+ sshfs.remote_uid = stbuf.st_uid;
+ sshfs.local_uid = getuid();
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ sshfs.remote_gid = stbuf.st_gid;
+ sshfs.local_gid = getgid();
+ #endif
+@@ -2139,7 +2145,7 @@
+ buf_init(&buf, 0);
+ buf_add_path(&buf, path);
+ buf_add_uint32(&buf, SSH_FILEXFER_ATTR_UIDGID);
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (sshfs.remote_uid_detected) {
+ if (uid == sshfs.local_uid)
+ uid = sshfs.remote_uid;
+@@ -2230,7 +2236,7 @@
+ sf = g_new0(struct sshfs_file, 1);
+ list_init(&sf->write_reqs);
+ pthread_cond_init(&sf->write_finished, NULL);
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ pthread_mutex_init(&sf->file_lock, NULL);
+ #endif
+ /* Assume random read after open */
+@@ -2266,7 +2272,7 @@
+ }
+
+ if (!err) {
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (cache_enabled)
+ cache_add_attr(path, &stbuf, wrctr);
+ #else
+@@ -2275,7 +2281,7 @@
+ buf_finish(&sf->handle);
+ fi->fh = (unsigned long) sf;
+ } else {
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (cache_enabled)
+ cache_invalidate(path);
+ #else
+@@ -2335,11 +2341,11 @@
+
+ static void sshfs_file_put(struct sshfs_file *sf)
+ {
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ pthread_mutex_lock(&sf->file_lock);
+ #endif
+ sf->refs--;
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (!sf->refs) {
+ pthread_mutex_unlock(&sf->file_lock);
+ g_free(sf);
+@@ -2354,11 +2360,11 @@
+
+ static void sshfs_file_get(struct sshfs_file *sf)
+ {
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ pthread_mutex_lock(&sf->file_lock);
+ #endif
+ sf->refs++;
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ pthread_mutex_unlock(&sf->file_lock);
+ #endif
+ }
+@@ -3050,12 +3056,7 @@
+ exit(1);
+
+ case KEY_VERSION:
+-#if (__FreeBSD__ >= 10)
+- fprintf(stderr, "SSHFS version %s (MacFUSE SSHFS %s)\n",
+- PACKAGE_VERSION, MACFUSE_SSHFS_VERSION);
+-#else
+ fprintf(stderr, "SSHFS version %s\n", PACKAGE_VERSION);
+-#endif
+ #if FUSE_VERSION >= 25
+ fuse_opt_add_arg(outargs, "--version");
+ sshfs_fuse_main(outargs);
+@@ -3139,7 +3140,7 @@
+ perror("Failed to allocate locked page for password");
+ return -1;
+ }
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (mlock(sshfs.password, size) != 0) {
+ memset(sshfs.password, 0, size);
+ munmap(sshfs.password, size);
+@@ -3147,7 +3148,7 @@
+ perror("Failed to allocate locked page for password");
+ return -1;
+ }
+-#endif /* __FreeBSD__ >= 10 */
++#endif /* __APPLE__ */
+
+ /* Don't use fgets() because password might stay in memory */
+ for (n = 0; n < max_password; n++) {
+@@ -3279,13 +3280,13 @@
+ }
+ #endif
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ int main(int argc, char *argv[], __unused char *envp[], char **exec_path)
+ #else
+ int main(int argc, char *argv[])
+ #endif
+ {
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ if (!realpath(*exec_path, sshfs_program_path)) {
+ memset(sshfs_program_path, 0, PATH_MAX);
+ }
+@@ -3298,10 +3299,10 @@
+ const char *sftp_server;
+ int libver;
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ /* Until this gets fixed somewhere else. */
+ g_slice_set_config(G_SLICE_CONFIG_ALWAYS_MALLOC, TRUE);
+-#endif /* __FreeBSD__ >= 10 */
++#endif /* __APPLE__ */
+ g_thread_init(NULL);
+
+ sshfs.blksize = 4096;
+@@ -3309,11 +3310,11 @@
+ sshfs.max_write = 65536;
+ sshfs.nodelay_workaround = 1;
+ sshfs.nodelaysrv_workaround = 0;
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ sshfs.rename_workaround = 1;
+ #else
+ sshfs.rename_workaround = 0;
+-#endif /* __FreeBSD__ >= 10 */
++#endif /* __APPLE__ */
+ sshfs.truncate_workaround = 0;
+ sshfs.buflimit_workaround = 1;
+ sshfs.ssh_ver = 2;
+@@ -3326,7 +3327,7 @@
+ ssh_add_arg("-a");
+ ssh_add_arg("-oClearAllForwardings=yes");
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ sshfs.detect_uid = 1;
+ #endif
+
+--- sshfs-fuse-2.2/cache.h.orig 2011-07-23 19:42:35.000000000 -0400
++++ sshfs-fuse-2.2/cache.h 2011-07-23 19:48:15.000000000 -0400
+@@ -28,6 +28,6 @@
+ void cache_invalidate(const char *path);
+ uint64_t cache_get_write_ctr(void);
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ extern int cache_enabled;
+ #endif
+--- sshfs-fuse-2.2/cache.c.orig 2011-07-23 19:42:33.000000000 -0400
++++ sshfs-fuse-2.2/cache.c 2011-07-23 19:47:52.000000000 -0400
+@@ -559,7 +559,7 @@
+ cache.next_oper = oper;
+
+ cache_unity_fill(oper, &cache_oper);
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ cache_enabled = cache.on;
+ #endif
+ if (cache.on) {
+@@ -597,6 +597,6 @@
+ return fuse_opt_parse(args, &cache, cache_opts, NULL);
+ }
+
+-#if (__FreeBSD__ >= 10)
++#ifdef __APPLE__
+ int cache_enabled;
+ #endif
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110725/6a108440/attachment-0001.html>
More information about the macports-changes
mailing list