summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Ismael Haase Hernandez <hahj87@gmail.com>2011-05-29 18:44:01 -0500
committerJoshua Ismael Haase Hernandez <hahj87@gmail.com>2011-05-29 18:44:01 -0500
commit281b44f8a67bac1be5ccc8697e355758e3852a79 (patch)
treea28213affedd8db040d310289dea787d6bbfe8cd
parentedf6965e83a24919183a069139792ee4d83b0a61 (diff)
parenta422536e1ba326bff507ba81859c784a135d1804 (diff)
Merge branch 'master' of vparabola:~/abslibre-pre-mips64el
-rw-r--r--community-testing/vhba-module/PKGBUILD27
-rw-r--r--community-testing/vhba-module/vhba-kernel2.6.37.patch56
-rw-r--r--community-testing/vhba-module/vhba-module.install16
-rw-r--r--community/balsa/PKGBUILD46
-rw-r--r--community/balsa/balsa.install6
-rw-r--r--community/calibre/PKGBUILD10
-rw-r--r--community/calibre/desktop_integration.patch14
-rw-r--r--community/epdfview/PKGBUILD33
-rw-r--r--community/flowcanvas/PKGBUILD6
-rw-r--r--community/flowcanvas/flowcanvas.install4
-rw-r--r--community/gitg/PKGBUILD11
-rw-r--r--community/mythplugins/PKGBUILD4
-rw-r--r--community/mythtv/PKGBUILD15
-rw-r--r--community/mythtv/mythtv-v4l2-fix.patch724
-rw-r--r--community/qtractor/PKGBUILD6
-rw-r--r--community/qtractor/qtractor.changelog31
-rw-r--r--core/openvpn/PKGBUILD6
-rw-r--r--extra/bluez/PKGBUILD9
-rw-r--r--extra/jack/PKGBUILD6
-rw-r--r--extra/jack/jack.changelog6
-rw-r--r--extra/pango/PKGBUILD4
-rw-r--r--extra/pyalpm/PKGBUILD23
-rw-r--r--extra/telepathy-logger/PKGBUILD6
-rw-r--r--extra/thunar/PKGBUILD8
-rw-r--r--extra/v4l-utils/PKGBUILD7
-rw-r--r--extra/xfce4-sensors-plugin/PKGBUILD16
-rw-r--r--extra/xfdesktop/PKGBUILD10
-rw-r--r--testing/re-alpine/PKGBUILD38
-rw-r--r--testing/re-alpine/maildir.patch3712
29 files changed, 4709 insertions, 151 deletions
diff --git a/community-testing/vhba-module/PKGBUILD b/community-testing/vhba-module/PKGBUILD
new file mode 100644
index 000000000..43fa2bc67
--- /dev/null
+++ b/community-testing/vhba-module/PKGBUILD
@@ -0,0 +1,27 @@
+# $Id: PKGBUILD 48166 2011-05-29 11:57:10Z mherych $
+# Maintainer: Mateusz Herych <heniekk@gmail.com>
+# Contributor: Charles Lindsay <charles@chaoslizard.org>
+
+pkgname=vhba-module
+pkgver=20100822
+_kernver='2.6.39-ARCH'
+pkgrel=5
+pkgdesc="Kernel module that emulates SCSI devices"
+arch=('i686' 'x86_64')
+url="http://cdemu.sourceforge.net/"
+license=('GPL2')
+depends=('kernel26>=2.6.39' 'kernel26<2.6.40')
+makedepends=('kernel26-headers>=2.6.39' 'git')
+install=vhba-module.install
+source=(http://downloads.sourceforge.net/cdemu/$pkgname-$pkgver.tar.gz
+ vhba-kernel2.6.37.patch)
+md5sums=('1d2f06ae33c5d15b7c29e467e4658aa2'
+ 'f0499fc54f6ef9b8d6ca0b9e940c5906')
+
+build() {
+ cd "$srcdir/$pkgname-$pkgver"
+ git apply -p2 ../vhba-kernel2.6.37.patch
+ make -j1 KDIR=/usr/src/linux-${_kernver} || return 1
+ install -D vhba.ko "$pkgdir/lib/modules/${_kernver}/extra/vhba.ko" || return 1
+ sed -i -e "s/KERNEL_VERSION='.*'/KERNEL_VERSION='${_kernver}'/" "$startdir/vhba-module.install"
+}
diff --git a/community-testing/vhba-module/vhba-kernel2.6.37.patch b/community-testing/vhba-module/vhba-kernel2.6.37.patch
new file mode 100644
index 000000000..e2b619c74
--- /dev/null
+++ b/community-testing/vhba-module/vhba-kernel2.6.37.patch
@@ -0,0 +1,56 @@
+From 9ad7ec7fae387f05249b9f4e6accb3bc3b0b8b0f Mon Sep 17 00:00:00 2001
+From: Alexandre Rostovtsev <tetromino@gmail.com>
+Date: Thu, 6 Jan 2011 03:39:26 -0500
+Subject: [PATCH] Make vhba compatible with kernel 2.6.37 SCSI host API
+
+Due to the SCSI host lock push-down changes introduced in 2.6.37 (see
+http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=f281233d3eba15fb225d21ae2e228fd4553d824a
+for more details), trying to use current vhba on 2.6.37 leads to oopses
+and kernel panics - e.g. see http://bugs.gentoo.org/show_bug.cgi?id=350753
+
+Add some #ifdefs to enable compatibility both with 2.6.37 and older API.
+Note that if future kernel versions remove the DEF_SCSI_QCMD macro, this
+issue will need to be revisited.
+
+Signed-off-by: Alexandre Rostovtsev <tetromino@gmail.com>
+---
+ vhba-module/vhba.c | 9 ++++++++-
+ 1 files changed, 8 insertions(+), 1 deletions(-)
+
+diff --git a/vhba-module/vhba.c b/vhba-module/vhba.c
+index 059f6ce..9d13016 100644
+--- a/vhba-module/vhba.c
++++ b/vhba-module/vhba.c
+@@ -27,6 +27,7 @@
+ #include <linux/miscdevice.h>
+ #include <linux/poll.h>
+ #include <linux/slab.h>
++#include <linux/version.h>
+ #ifdef CONFIG_COMPAT
+ #include <linux/compat.h>
+ #endif
+@@ -363,7 +364,7 @@ static void vhba_free_command(struct vhba_command *vcmd)
+ spin_unlock_irqrestore(&vhost->cmd_lock, flags);
+ }
+
+-static int vhba_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
++static int vhba_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+ {
+ struct vhba_device *vdev;
+ int retval;
+@@ -388,6 +389,12 @@ static int vhba_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmn
+ return retval;
+ }
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
++DEF_SCSI_QCMD(vhba_queuecommand)
++#else
++#define vhba_queuecommand vhba_queuecommand_lck
++#endif
++
+ static int vhba_abort(struct scsi_cmnd *cmd)
+ {
+ struct vhba_device *vdev;
+--
+1.7.3.4
+
diff --git a/community-testing/vhba-module/vhba-module.install b/community-testing/vhba-module/vhba-module.install
new file mode 100644
index 000000000..c3bcbca3f
--- /dev/null
+++ b/community-testing/vhba-module/vhba-module.install
@@ -0,0 +1,16 @@
+post_install() {
+ echo ">> Place 'vhba' in MODULES= in /etc/rc.conf to enable vhba on system boot."
+ echo ">> This module needs to be recompiled for every kernel version upgrade."
+ KERNEL_VERSION='2.6.37-ARCH'
+ depmod $KERNEL_VERSION > /dev/null 2>&1
+}
+
+post_upgrade() {
+ post_install
+}
+
+post_remove() {
+ KERNEL_VERSION='2.6.37-ARCH'
+ depmod $KERNEL_VERSION > /dev/null 2>&1
+}
+
diff --git a/community/balsa/PKGBUILD b/community/balsa/PKGBUILD
index 658dbb1a9..a69250356 100644
--- a/community/balsa/PKGBUILD
+++ b/community/balsa/PKGBUILD
@@ -1,36 +1,44 @@
-# $Id: PKGBUILD 41737 2011-03-08 18:04:34Z ibiru $
+# $Id: PKGBUILD 48198 2011-05-29 16:56:14Z bfanella $
# Maintainer : Ionut Biru <ibiru@archlinux.org>
+# Maintainer: Brad Fanella <bradfanella@archlinux.us>
# Contributor: Roman Kyrylych <roman@archlinux.org>
pkgname=balsa
pkgver=2.4.9
-pkgrel=1
+pkgrel=3
pkgdesc="An e-mail client for GNOME"
arch=('i686' 'x86_64' 'mips64el')
license=('GPL')
url='http://pawsa.fedorapeople.org/balsa/'
-depends=('gmime' 'gtkhtml' 'libesmtp' 'libnotify' 'gpgme' 'gtksourceview2' 'gtkspell')
+depends=('libgssglue' 'gmime' 'libwebkit' 'libesmtp' 'libnotify' 'gpgme' 'gtksourceview2' 'gtkspell' 'gnome-icon-theme')
makedepends=('perlxml' 'gnome-doc-utils' 'intltool' 'namcap')
install=balsa.install
source=(http://pawsa.fedorapeople.org/${pkgname}/${pkgname}-${pkgver}.tar.bz2)
md5sums=('bd7ac44f0cf3117a5fdb46d17dac2b51')
build() {
- cd "${srcdir}/${pkgname}-${pkgver}"
+ cd ${srcdir}/${pkgname}-${pkgver}
- ./configure --prefix=/usr \
- --sysconfdir=/etc \
- --localstatedir=/var \
- --with-ssl \
- --with-gpgme=gpgme-config \
- --with-gss \
- --with-ldap \
- --with-gtksourceview \
- --with-gtkspell \
- --with-rubrica \
- --with-sqlite \
- --without-nm \
- --without-gnome
- make
- make GTK_UPDATE_ICON_CACHE=/bin/true DESTDIR="${pkgdir}" install
+ ./configure --prefix=/usr \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --with-ssl \
+ --with-gpgme=gpgme-config \
+ --with-gss \
+ --with-ldap \
+ --with-gtksourceview \
+ --with-gtkspell \
+ --with-rubrica \
+ --with-sqlite \
+ --without-nm \
+ --without-gnome \
+ --with-html-widget=webkit
+
+ make
+}
+
+package() {
+ cd ${srcdir}/${pkgname}-${pkgver}
+
+ make GTK_UPDATE_ICON_CACHE=/bin/true DESTDIR="${pkgdir}" install
}
diff --git a/community/balsa/balsa.install b/community/balsa/balsa.install
index 17ca8f78a..cb9a7a5c3 100644
--- a/community/balsa/balsa.install
+++ b/community/balsa/balsa.install
@@ -1,11 +1,11 @@
post_install() {
- gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
+ gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
}
post_upgrade() {
- post_install $1
+ post_install $1
}
post_remove() {
- post_install $1
+ post_install $1
}
diff --git a/community/calibre/PKGBUILD b/community/calibre/PKGBUILD
index 9ec165ff9..7d368870d 100644
--- a/community/calibre/PKGBUILD
+++ b/community/calibre/PKGBUILD
@@ -1,11 +1,11 @@
-# $Id: PKGBUILD 47955 2011-05-26 11:34:38Z giovanni $
+# $Id: PKGBUILD 48179 2011-05-29 13:13:23Z giovanni $
# Maintainer: Giovanni Scafora <giovanni@archlinux.org>
# Contributor: Petrov Roman <nwhisper@gmail.com>
# Contributor: Andrea Fagiani <andfagiani _at_ gmail dot com>
pkgname=calibre
-pkgver=0.8.2
-pkgrel=2
+pkgver=0.8.3
+pkgrel=1
pkgdesc="Ebook management application"
arch=('i686' 'x86_64')
url="http://calibre-ebook.com/"
@@ -20,8 +20,8 @@ optdepends=('ipython: to use calibre-debug')
install=calibre.install
source=(http://downloads.sourceforge.net/${pkgname}/${pkgname}-${pkgver}.tar.gz
desktop_integration.patch)
-md5sums=('e64c92ccf29ac17bfaf4a296e17a38ba'
- 'bcc538a3b004429bf8f5a0ac1d89a37f')
+md5sums=('aee05cac444f68491f2a3d68b22da53e'
+ 'f4b80e3b34e34bce68b3f052ff52dee8')
build() {
cd "${srcdir}/${pkgname}"
diff --git a/community/calibre/desktop_integration.patch b/community/calibre/desktop_integration.patch
index fa58443ed..40d48c03e 100644
--- a/community/calibre/desktop_integration.patch
+++ b/community/calibre/desktop_integration.patch
@@ -1,7 +1,6 @@
-diff -rupN calibre.orig//src/calibre/linux.py calibre/src/calibre/linux.py
---- calibre.orig//src/calibre/linux.py 2010-09-17 22:38:02.000000000 +0200
-+++ calibre/src/calibre/linux.py 2010-09-19 15:50:15.029705851 +0200
-@@ -334,52 +323,39 @@ class PostInstall:
+--- a/src/calibre/linux.py 2011-05-27 18:42:14.000000000 +0200
++++ b/src/calibre/linux.py 2011-05-29 14:57:49.000000000 +0200
+@@ -340,51 +340,39 @@
with TemporaryDirectory() as tdir:
with CurrentDir(tdir):
@@ -26,7 +25,7 @@ diff -rupN calibre.orig//src/calibre/linux.py calibre/src/calibre/linux.py
mimetypes = set([])
for x in all_input_formats():
mt = guess_type('dummy.'+x)[0]
-- if mt and 'chemical' not in mt:
+- if mt and 'chemical' not in mt and 'ctc-posml' not in mt:
+ if mt and 'chemical' not in mt and 'text' not in mt and 'pdf' not in mt and 'xhtml' not in mt:
mimetypes.add(mt)
@@ -52,11 +51,10 @@ diff -rupN calibre.orig//src/calibre/linux.py calibre/src/calibre/linux.py
- des = ('calibre-gui.desktop', 'calibre-lrfviewer.desktop',
- 'calibre-ebook-viewer.desktop')
- for x in des:
-- cmd = ['xdg-desktop-menu', 'install', './'+x]
-- if x != des[-1]:
-- cmd.insert(2, '--noupdate')
+- cmd = ['xdg-desktop-menu', 'install', '--noupdate', './'+x]
- check_call(' '.join(cmd), shell=True)
- self.menu_resources.append(x)
+- check_call(['xdg-desktop-menu', 'forceupdate'])
- f = open('calibre-mimetypes', 'wb')
+ dir = os.path.join(self.opts.staging_sharedir,'../mime/packages/')
+ os.makedirs(dir)
diff --git a/community/epdfview/PKGBUILD b/community/epdfview/PKGBUILD
index 1c11e43d0..26db195b6 100644
--- a/community/epdfview/PKGBUILD
+++ b/community/epdfview/PKGBUILD
@@ -1,42 +1,27 @@
-# $Id: PKGBUILD 39086 2011-02-06 14:04:55Z schuay $
+# $Id: PKGBUILD 48161 2011-05-29 11:36:51Z schuay $
+# Maintainer: schuay <jakob.gruber@gmail.com>
# Contributor: Tom K <tomk@runbox.com>
# Contributor: Thayer Williams <thayer@archlinux.org>
-# Maintainer: schuay <jakob.gruber@gmail.com>
pkgname=epdfview
-pkgver=0.1.7
-pkgrel=9
+pkgver=0.1.8
+pkgrel=1
pkgdesc="A free lightweight PDF document viewer."
url="http://www.emma-soft.com/projects/epdfview/"
arch=('i686' 'x86_64' 'mips64el')
license=('GPL')
-depends=('poppler-glib>=0.16.2' 'desktop-file-utils' 'hicolor-icon-theme')
+depends=('poppler-glib' 'desktop-file-utils' 'hicolor-icon-theme')
makedepends=('pkgconfig')
install='epdfview.install'
source=("http://www.emma-soft.com/projects/${pkgname}/chrome/site/releases/${pkgname}-${pkgver}.tar.bz2"
- "${pkgname}.desktop.patch"
- "0001-r329.patch"
- "0002-r354.patch"
- "0003-r357.patch"
- "m_Linearized.patch")
-md5sums=('1919bb19c16ef0a97d48b0a8303d3c7b'
- 'fbf22bbabdbb7544db615ac5775d57e2'
- '14397ae0baa69fb9791ccaa35c243470'
- '45a3b7d56f28f94a230c476ce2de54f0'
- '932da23c324326c5baea3b5beae12ad5'
- '53fe971f039a4aaf1243e60d59973cf6')
+ "${pkgname}.desktop.patch")
+md5sums=('e50285b01612169b2594fea375f53ae4'
+ 'fbf22bbabdbb7544db615ac5775d57e2')
build() {
cd "${srcdir}/${pkgname}-${pkgver}"
- patch -Np0 -i "${srcdir}/${pkgname}.desktop.patch"
- patch -Np2 -i "${srcdir}/0001-r329.patch" # fixes mousewheel scrolling.
- patch -Np2 -i "${srcdir}/0002-r354.patch" # patches poppler api changes, can
- patch -Np2 -i "${srcdir}/0003-r357.patch" # be removed with a new epdfview release.
- patch -Np0 -i "${srcdir}/m_Linearized.patch" # fix segfault on close.
- # apply changes from r354 and r357 to configure.ac
- touch ChangeLog # missing ChangeLog results in
- autoreconf -fi # error during autoreconf
+ patch -Np0 -i "${srcdir}/${pkgname}.desktop.patch"
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
make
diff --git a/community/flowcanvas/PKGBUILD b/community/flowcanvas/PKGBUILD
index c18fa4ceb..ce145f515 100644
--- a/community/flowcanvas/PKGBUILD
+++ b/community/flowcanvas/PKGBUILD
@@ -1,13 +1,13 @@
-# $Id: PKGBUILD 37633 2011-01-15 21:43:11Z schiv $
+# $Id: PKGBUILD 48184 2011-05-29 16:00:31Z schiv $
# Maintainer: Ray Rashif <schiv@archlinux.org>
# Contributor: Max a.k.a. Synthead <synthead@gmail.com>
# Contributor: christhemonkey <christhemonkey at gmail dot com>
pkgname=flowcanvas
pkgver=0.7.1
-pkgrel=1
+pkgrel=2
pkgdesc="Gtkmm/Gnomecanvasmm widget for boxes-and-lines style environments"
-arch=(i686 x86_64 'mips64el')
+arch=('i686' 'x86_64')
url="http://drobilla.net/software/flowcanvas/"
depends=('libgnomecanvasmm' 'graphviz')
makedepends=('boost' 'python2')
diff --git a/community/flowcanvas/flowcanvas.install b/community/flowcanvas/flowcanvas.install
index 46f265d5b..dbd9898d3 100644
--- a/community/flowcanvas/flowcanvas.install
+++ b/community/flowcanvas/flowcanvas.install
@@ -1,5 +1,5 @@
post_install() {
- /sbin/ldconfig
+ \ldconfig
}
post_upgrade() {
@@ -9,3 +9,5 @@ post_upgrade() {
post_remove() {
post_install
}
+
+# vim:set ts=2 sw=2 et:
diff --git a/community/gitg/PKGBUILD b/community/gitg/PKGBUILD
index 844904dc5..85e407649 100644
--- a/community/gitg/PKGBUILD
+++ b/community/gitg/PKGBUILD
@@ -1,21 +1,22 @@
# Maintainer: Brad Fanella <bradfanella@archlinux.us>
+# Contributor: Blaž Tomžič <blaz.tomazic@gmail.com>
# Contributor: Thomas Dziedzic < gostrc at gmail >
# Contributor: Christoph Zeiler <archNOSPAM_at_moonblade.dot.org>
# Contributor: M Rawash <mrawash@gmail.com>
# Contributor: DonVla <donvla@users.sourceforge.net>
pkgname=gitg
-pkgver=0.1.2
-pkgrel=1
+pkgver=0.2.2
+pkgrel=2
pkgdesc='A GIT repository viewer based on GTK+'
arch=('i686' 'x86_64' 'mips64el')
url='http://trac.novowork.com/gitg/'
license=('GPL')
-depends=('gconf' 'gtksourceview2' 'git' 'desktop-file-utils' 'gsettings-desktop-schemas')
+depends=('dconf' 'gtksourceview3' 'git' 'desktop-file-utils' 'gsettings-desktop-schemas')
makedepends=('intltool')
install="${pkgname}.install"
-source=("ftp://ftp.gnome.org/pub/GNOME/sources/gitg/0.1/${pkgname}-${pkgver}.tar.bz2")
-sha256sums=('e7030b7d49169339f123c79eb6f289d9d1067fd5b248b7ce712a7b15a72e9f1a')
+source=("ftp://ftp.gnome.org/pub/GNOME/sources/gitg/0.2/${pkgname}-${pkgver}.tar.bz2")
+sha256sums=('cfa1b1d2bdd1211c09e00dca42130ea98e98fde576d85e18eabfde1802d0d04a')
build() {
cd ${pkgname}-${pkgver}
diff --git a/community/mythplugins/PKGBUILD b/community/mythplugins/PKGBUILD
index e3ec00716..7d6bbfc3d 100644
--- a/community/mythplugins/PKGBUILD
+++ b/community/mythplugins/PKGBUILD
@@ -1,4 +1,4 @@
-# $Id: PKGBUILD 47935 2011-05-26 08:19:27Z jconder $
+# $Id: PKGBUILD 48174 2011-05-29 12:47:11Z jconder $
# Maintainer: Jonathan Conder <jonno.conder@gmail.com>
# Contributor: Giovanni Scafora <giovanni@archlinux.org>
@@ -15,7 +15,7 @@ pkgname=('mythplugins-mytharchive'
'mythplugins-mythweb'
'mythplugins-mythzoneminder')
pkgver=0.24.1
-pkgrel=3
+pkgrel=4
epoch=1
arch=('i686' 'x86_64')
url="http://www.mythtv.org"
diff --git a/community/mythtv/PKGBUILD b/community/mythtv/PKGBUILD
index 45b18a7bd..81422f0a5 100644
--- a/community/mythtv/PKGBUILD
+++ b/community/mythtv/PKGBUILD
@@ -1,4 +1,4 @@
-# $Id: PKGBUILD 47228 2011-05-19 08:27:51Z jconder $
+# $Id: PKGBUILD 48169 2011-05-29 12:28:03Z jconder $
# Maintainer: Jonathan Conder <jonno.conder@gmail.com>
# Contributor: Giovanni Scafora <giovanni@archlinux.org>
# Contributor: Juergen Hoetzel <juergen@archlinux.org>
@@ -7,7 +7,7 @@
pkgname=mythtv
pkgver=0.24.1
-pkgrel=1
+pkgrel=2
epoch=1
pkgdesc="A Homebrew PVR project"
arch=('i686' 'x86_64' 'mips64el')
@@ -23,15 +23,19 @@ backup=('etc/conf.d/mythbackend')
install='mythtv.install'
source=("ftp://ftp.osuosl.org/pub/$pkgname/$pkgname-$pkgver.tar.bz2"
'mythbackend.rc'
- 'mythbackend.conf')
+ 'mythbackend.conf'
+ 'mythtv-v4l2-fix.patch')
md5sums=('6870c679619ec58456e76839745411d8'
'feadcc9ad064d93d6dceab1efc0bd9ed'
- 'bb8e4033d82428d827570fae9ba15e6a')
+ 'bb8e4033d82428d827570fae9ba15e6a'
+ 'ba5c91df80f0d3f7563a873e71a3725c')
build() {
cd "$srcdir/$pkgname-$pkgver"
find 'bindings/python' 'contrib' -type f | xargs sed -i 's@^#!.*python$@#!/usr/bin/python2@'
+ patch -Np2 -i ${srcdir}/mythtv-v4l2-fix.patch
+
ARCH="${CARCH/_/-}"
./configure --prefix=/usr --cpu="$ARCH" \
--enable-mmx \
@@ -57,7 +61,8 @@ build() {
--enable-xrandr \
--enable-xv \
--enable-x11 \
- --with-bindings=perl,python --python=python2
+ --with-bindings=perl,python \
+ --python=python2
make
}
diff --git a/community/mythtv/mythtv-v4l2-fix.patch b/community/mythtv/mythtv-v4l2-fix.patch
new file mode 100644
index 000000000..e26e16615
--- /dev/null
+++ b/community/mythtv/mythtv-v4l2-fix.patch
@@ -0,0 +1,724 @@
+diff --git a/mythtv/configure b/mythtv/configure
+index 1efe803..7bcdf06 100755
+--- a/mythtv/configure
++++ b/mythtv/configure
+@@ -109,7 +109,8 @@ Advanced options (experts only):
+ --disable-iptv disable support for recording RTSP/UDP/RTP streams
+ --disable-hdhomerun disable support for HDHomeRun boxes
+ --disable-v4l disable Video4Linux support
+- --disable-ivtv disable ivtv support (PVR-x50) req. v4l support
++ --disable-v4l2 disable Video4Linux2 support
++ --disable-ivtv disable ivtv support (PVR-x50) req. v4l2 support
+ --disable-hdpvr disable HD-PVR support
+ --disable-dvb disable DVB support
+ --dvb-path=HDRLOC location of directory containing
+@@ -1315,6 +1316,7 @@ MYTHTV_CONFIG_LIST='
+ qtwebkit
+ quartz_video
+ v4l
++ v4l2
+ valgrind
+ x11
+ xrandr
+@@ -1706,8 +1708,8 @@ audio_oss_deps_any="soundcard_h sys_soundcard_h"
+ dvb_deps="backend"
+ firewire_deps="backend"
+ iptv_deps="backend"
+-ivtv_deps="backend v4l"
+-hdpvr_deps="backend v4l"
++ivtv_deps="backend v4l2"
++hdpvr_deps="backend v4l2"
+ hdhomerun_deps="backend"
+ mpegtsraw_demuxer_deps="merge_libavformat_mpegts_c"
+ mythtranscode_deps="backend frontend"
+@@ -1715,6 +1717,7 @@ opengl_deps_any="agl_h GL_gl_h darwin windows x11"
+ opengl_video_deps="opengl"
+ opengl_vsync_deps="opengl"
+ v4l_deps="backend linux_videodev_h linux_videodev2_h"
++v4l2_deps="backend linux_videodev2_h"
+ vdpau_deps="opengl vdpau_vdpau_h vdpau_vdpau_x11_h"
+ xrandr_deps="x11"
+ xv_deps="x11"
+@@ -1933,6 +1936,7 @@ enable opengl_vsync
+ enable opengl_video
+ enable quartz_video
+ enable v4l
++enable v4l2
+ enable x11
+ enable xrandr
+ enable xv
+@@ -3062,6 +3066,7 @@ EOF
+ fi
+ disable opengl_vsync
+ disable v4l
++ disable v4l2
+ disable x11
+ # Workaround compile errors from missing gmtime_r/localtime_r/uint def
+ CFLAGS=`echo $CFLAGS | sed 's/-D_POSIX_C_SOURCE=200112//'`
+@@ -3106,6 +3111,7 @@ EOF
+ fi
+ disable symver
+ disable v4l
++ disable v4l2
+ enable windows
+ disable x11
+ ###### Standard ffmpeg configure stuff follows:
+@@ -4375,6 +4381,7 @@ enabled stripping || strip="echo skipping strip"
+
+ if enabled backend; then
+ echo "Video4Linux sup. ${v4l-no}"
++ echo "Video4Linux2 sup. ${v4l2-no}"
+ echo "ivtv support ${ivtv-no}"
+ echo "HD-PVR support ${hdpvr-no}"
+ echo "FireWire support ${firewire-no}"
+diff --git a/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp b/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
+index 739634d..39e5956 100644
+--- a/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
++++ b/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
+@@ -42,9 +42,13 @@ extern "C" {
+ #include "libswscale/swscale.h"
+ }
+
++#if defined(USING_V4L) || defined(USING_V4L2)
+ #ifdef USING_V4L
+ #include <linux/videodev.h>
++#endif
++#ifdef USING_V4L2
+ #include <linux/videodev2.h>
++#endif
+
+ #include "go7007_myth.h"
+
+@@ -55,9 +59,9 @@ extern "C" {
+ extern "C" {
+ #include "vbitext/vbi.h"
+ }
+-#else // USING_V4l
++#else // USING_V4L || USING_V4L2
+ #define VT_WIDTH 0
+-#endif // USING_V4l
++#endif // USING_V4l || USING_V4L2
+
+ #define KEYFRAMEDIST 30
+
+@@ -1019,7 +1023,7 @@ bool NuppelVideoRecorder::Open(void)
+
+ void NuppelVideoRecorder::ProbeV4L2(void)
+ {
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ usingv4l2 = true;
+
+ struct v4l2_capability vcap;
+@@ -1049,7 +1053,7 @@ void NuppelVideoRecorder::ProbeV4L2(void)
+ QString driver = (char *)vcap.driver;
+ if (driver == "go7007")
+ go7007 = true;
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+ }
+
+ void NuppelVideoRecorder::StartRecording(void)
+@@ -2460,7 +2464,7 @@ void NuppelVideoRecorder::doAudioThread(void)
+ audio_device->Close();
+ }
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ struct VBIData
+ {
+ NuppelVideoRecorder *nvr;
+@@ -2634,9 +2638,9 @@ void NuppelVideoRecorder::FormatTeletextSubtitles(struct VBIData *vbidata)
+ act_text_buffer = 0;
+ textbuffer[act]->freeToEncode = 1;
+ }
+-#else // USING_V4L
++#else // USING_V4L || USING_V4L2
+ void NuppelVideoRecorder::FormatTeletextSubtitles(struct VBIData *vbidata) {}
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+
+ void NuppelVideoRecorder::FormatCC(struct cc *cc)
+ {
+@@ -2863,7 +2867,7 @@ void NuppelVideoRecorder::doVbiThread(void)
+ //VERBOSE(VB_RECORD, LOC + "vbi end");
+ }
+
+-#else // USING_V4L
++#else // USING_V4L
+ void NuppelVideoRecorder::doVbiThread(void) { }
+ #endif // USING_V4L
+
+diff --git a/mythtv/libs/libmythtv/analogsignalmonitor.cpp b/mythtv/libs/libmythtv/analogsignalmonitor.cpp
+index 2a4f4c5..fa5823a 100644
+--- a/mythtv/libs/libmythtv/analogsignalmonitor.cpp
++++ b/mythtv/libs/libmythtv/analogsignalmonitor.cpp
+@@ -6,7 +6,9 @@
+ #include <sys/ioctl.h>
+ #include <poll.h>
+
++#ifdef USING_V4L
+ #include <linux/videodev.h>
++#endif
+
+ #include "mythverbose.h"
+ #include "analogsignalmonitor.h"
+@@ -151,6 +153,7 @@ void AnalogSignalMonitor::UpdateValues(void)
+ }
+ else
+ {
++#ifdef USING_V4L
+ struct video_tuner tuner;
+ bzero(&tuner, sizeof(tuner));
+
+@@ -163,6 +166,7 @@ void AnalogSignalMonitor::UpdateValues(void)
+ {
+ isLocked = tuner.signal;
+ }
++#endif
+ }
+
+ {
+diff --git a/mythtv/libs/libmythtv/cardutil.cpp b/mythtv/libs/libmythtv/cardutil.cpp
+index 8852682..494f48a 100644
+--- a/mythtv/libs/libmythtv/cardutil.cpp
++++ b/mythtv/libs/libmythtv/cardutil.cpp
+@@ -4,7 +4,7 @@
+
+ #include <algorithm>
+
+-#if defined(USING_V4L) || defined(USING_DVB)
++#if defined(USING_V4L) || defined(USING_V4L2) || defined(USING_DVB)
+ #include <sys/ioctl.h>
+ #endif
+
+@@ -28,6 +28,8 @@
+
+ #ifdef USING_V4L
+ #include <linux/videodev.h>
++#endif
++#ifdef USING_V4L2
+ #include <linux/videodev2.h>
+ #endif
+
+@@ -1455,15 +1457,15 @@ uint CardUtil::GetQuickTuning(uint cardid, const QString &input_name)
+ bool CardUtil::hasV4L2(int videofd)
+ {
+ (void) videofd;
+-#ifdef USING_V4L
++#ifdef USING_V4L2
+ struct v4l2_capability vcap;
+ bzero(&vcap, sizeof(vcap));
+
+ return ((ioctl(videofd, VIDIOC_QUERYCAP, &vcap) >= 0) &&
+ (vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE));
+-#else // if !USING_V4L
++#else // if !USING_V4L2
+ return false;
+-#endif // !USING_V4L
++#endif // !USING_V4L2
+ }
+
+ bool CardUtil::GetV4LInfo(
+@@ -1475,7 +1477,7 @@ bool CardUtil::GetV4LInfo(
+ if (videofd < 0)
+ return false;
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ // First try V4L2 query
+ struct v4l2_capability capability;
+ bzero(&capability, sizeof(struct v4l2_capability));
+@@ -1487,11 +1489,13 @@ bool CardUtil::GetV4LInfo(
+ }
+ else // Fallback to V4L1 query
+ {
++#ifdef USING_V4L
+ struct video_capability capability;
+ if (ioctl(videofd, VIDIOCGCAP, &capability) >= 0)
+ card = QString::fromAscii((const char*)capability.name);
++#endif //USING_V4L
+ }
+-#endif // !USING_V4L
++#endif // !USING_V4L || USING_V4L2
+
+ if (!driver.isEmpty())
+ driver.remove( QRegExp("\\[[0-9]\\]$") );
+@@ -1506,9 +1510,9 @@ InputNames CardUtil::ProbeV4LVideoInputs(int videofd, bool &ok)
+ InputNames list;
+ ok = false;
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ bool usingv4l2 = hasV4L2(videofd);
+-
++#ifdef USING_V4L2
+ // V4L v2 query
+ struct v4l2_input vin;
+ bzero(&vin, sizeof(vin));
+@@ -1523,8 +1527,10 @@ InputNames CardUtil::ProbeV4LVideoInputs(int videofd, bool &ok)
+ ok = true;
+ return list;
+ }
++#endif
+
+ // V4L v1 query
++#ifdef USING_V4L
+ struct video_capability vidcap;
+ bzero(&vidcap, sizeof(vidcap));
+ if (ioctl(videofd, VIDIOCGCAP, &vidcap) != 0)
+@@ -1552,15 +1558,15 @@ InputNames CardUtil::ProbeV4LVideoInputs(int videofd, bool &ok)
+
+ list[i] = test.name;
+ }
+-
++#endif
+ // Create an input on single input cards that don't advertise input
+ if (!list.size())
+ list[0] = "Television";
+
+ ok = true;
+-#else // if !USING_V4L
++#else // if !USING_V4L || USING_V4L2
+ list[-1] += QObject::tr("ERROR, Compile with V4L support to query inputs");
+-#endif // !USING_V4L
++#endif // !USING_V4L || USING_V4L2
+ return list;
+ }
+
+diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
+index 832d0a8..e35b186 100644
+--- a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
++++ b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
+@@ -1394,7 +1394,7 @@ const DVBChannel *ChannelScanSM::GetDVBChannel(void) const
+
+ V4LChannel *ChannelScanSM::GetV4LChannel(void)
+ {
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ return dynamic_cast<V4LChannel*>(channel);
+ #else
+ return NULL;
+diff --git a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
+index 1595d6a..4d2b2cf 100644
+--- a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
++++ b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
+@@ -342,7 +342,7 @@ void ChannelScanner::PreScanCommon(
+ channel = new DVBChannel(device);
+ #endif
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ if (("V4L" == card_type) || ("MPEG" == card_type))
+ channel = new V4LChannel(NULL, device);
+ #endif
+diff --git a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
+index 00fd9d3..70e3469 100644
+--- a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
++++ b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
+@@ -27,14 +27,14 @@ static QString card_types(void)
+ cardTypes += "'DVB'";
+ #endif // USING_DVB
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ if (!cardTypes.isEmpty())
+ cardTypes += ",";
+ cardTypes += "'V4L'";
+ # ifdef USING_IVTV
+ cardTypes += ",'MPEG'";
+ # endif // USING_IVTV
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+
+ #ifdef USING_IPTV
+ if (!cardTypes.isEmpty())
+diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro
+index 3d26e0a..ea06ee7 100644
+--- a/mythtv/libs/libmythtv/libmythtv.pro
++++ b/mythtv/libs/libmythtv/libmythtv.pro
+@@ -119,7 +119,7 @@ cygwin:DEFINES += _WIN32
+ using_valgrind:DEFINES += USING_VALGRIND
+
+ # old libvbitext (Caption decoder)
+-using_v4l {
++using_v4l || using_v4l2 {
+ HEADERS += vbitext/cc.h vbitext/dllist.h vbitext/hamm.h vbitext/lang.h
+ HEADERS += vbitext/vbi.h vbitext/vt.h
+ SOURCES += vbitext/cc.cpp vbitext/vbi.c vbitext/hamm.c vbitext/lang.c
+@@ -471,11 +471,17 @@ using_backend {
+ SOURCES += channelchangemonitor.cpp
+
+ # Support for Video4Linux devices
+- using_v4l {
++ using_v4l || using_v4l2 {
+ HEADERS += v4lchannel.h analogsignalmonitor.h
+ SOURCES += v4lchannel.cpp analogsignalmonitor.cpp
+
+- DEFINES += USING_V4L
++ using_v4l {
++ DEFINES += USING_V4L
++ }
++
++ using_v4l2 {
++ DEFINES += USING_V4L2
++ }
+ }
+
+ # Support for cable boxes that provide Firewire out
+diff --git a/mythtv/libs/libmythtv/signalmonitor.cpp b/mythtv/libs/libmythtv/signalmonitor.cpp
+index 221efef..c199b3b 100644
+--- a/mythtv/libs/libmythtv/signalmonitor.cpp
++++ b/mythtv/libs/libmythtv/signalmonitor.cpp
+@@ -23,7 +23,7 @@ extern "C" {
+ # include "dvbchannel.h"
+ #endif
+
+-#ifdef USING_V4L
++#ifdef USING_V4L2
+ # include "analogsignalmonitor.h"
+ # include "v4lchannel.h"
+ #endif
+@@ -95,7 +95,7 @@ SignalMonitor *SignalMonitor::Init(QString cardtype, int db_cardnum,
+ }
+ #endif
+
+-#ifdef USING_V4L
++#ifdef USING_V4L2
+ if ((cardtype.toUpper() == "HDPVR"))
+ {
+ V4LChannel *chan = dynamic_cast<V4LChannel*>(channel);
+diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp
+index b885eaa..3d9c7ad 100644
+--- a/mythtv/libs/libmythtv/tv_rec.cpp
++++ b/mythtv/libs/libmythtv/tv_rec.cpp
+@@ -57,7 +57,7 @@ using namespace std;
+
+ #include "channelgroup.h"
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ #include "v4lchannel.h"
+ #endif
+
+@@ -206,7 +206,7 @@ bool TVRec::CreateChannel(const QString &startchannel)
+ }
+ else // "V4L" or "MPEG", ie, analog TV
+ {
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ channel = new V4LChannel(this, genOpt.videodev);
+ if (!channel->Open())
+ return false;
+@@ -1082,11 +1082,11 @@ bool TVRec::SetupRecorder(RecordingProfile &profile)
+ }
+ else
+ {
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ // V4L/MJPEG/GO7007 from here on
+ recorder = new NuppelVideoRecorder(this, channel);
+ recorder->SetOption("skipbtaudio", genOpt.skip_btaudio);
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+ }
+
+ if (recorder)
+@@ -1292,11 +1292,11 @@ FirewireChannel *TVRec::GetFirewireChannel(void)
+
+ V4LChannel *TVRec::GetV4LChannel(void)
+ {
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ return dynamic_cast<V4LChannel*>(channel);
+ #else
+ return NULL;
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+ }
+
+ /** \fn TVRec::EventThread(void*)
+@@ -4137,7 +4137,7 @@ void TVRec::TuningNewRecorder(MPEGStreamData *streamData)
+ channel->GetCurrentName());
+ }
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ if (GetV4LChannel())
+ {
+ channel->InitPictureAttributes();
+diff --git a/mythtv/libs/libmythtv/v4lchannel.cpp b/mythtv/libs/libmythtv/v4lchannel.cpp
+index bc82b49..7aa47ef 100644
+--- a/mythtv/libs/libmythtv/v4lchannel.cpp
++++ b/mythtv/libs/libmythtv/v4lchannel.cpp
+@@ -16,8 +16,12 @@
+ #include <iostream>
+ using namespace std;
+
++#ifdef USING_V4L
+ #include <linux/videodev.h>
++#endif
++#ifdef USING_V4L2
+ #include <linux/videodev2.h>
++#endif
+
+ // MythTV headers
+ #include "v4lchannel.h"
+@@ -150,8 +154,10 @@ static int format_to_mode(const QString &fmt, int v4l_version)
+ {
+ if (fmt == "NTSC-JP")
+ return 6;
++#ifdef USING_V4L
+ else if (fmt.left(5) == "SECAM")
+ return VIDEO_MODE_SECAM;
++#endif
+ else if (fmt == "PAL-NC")
+ return 3;
+ else if (fmt == "PAL-M")
+@@ -159,6 +165,7 @@ static int format_to_mode(const QString &fmt, int v4l_version)
+ else if (fmt == "PAL-N")
+ return 5;
+ // generics...
++#ifdef USING_V4L
+ else if (fmt.left(3) == "PAL")
+ return VIDEO_MODE_PAL;
+ else if (fmt.left(4) == "NTSC")
+@@ -166,6 +173,7 @@ static int format_to_mode(const QString &fmt, int v4l_version)
+ else if (fmt.left(4) == "ATSC")
+ return VIDEO_MODE_NTSC; // We've dropped V4L ATSC support...
+ return VIDEO_MODE_NTSC;
++#endif
+ }
+
+ VERBOSE(VB_IMPORTANT,
+@@ -237,6 +245,7 @@ static QString mode_to_format(int mode, int v4l_version)
+ }
+ else if (1 == v4l_version)
+ {
++#ifdef USING_V4L
+ if (mode == VIDEO_MODE_NTSC)
+ return "NTSC";
+ else if (mode == VIDEO_MODE_PAL)
+@@ -249,6 +258,7 @@ static QString mode_to_format(int mode, int v4l_version)
+ return "PAL-N";
+ else if (mode == 6)
+ return "NTSC-JP";
++#endif
+ }
+ else
+ {
+@@ -676,6 +686,7 @@ bool V4LChannel::Tune(uint frequency, QString inputname,
+ return true;
+ }
+
++#ifdef USING_V4L
+ // Video4Linux version 1 tuning
+ uint freq = frequency / 62500;
+ ioctlval = ioctl(videofd, VIDIOCSFREQ, &freq);
+@@ -687,6 +698,7 @@ bool V4LChannel::Tune(uint frequency, QString inputname,
+ .arg(device).arg(ioctlval).arg(strerror(errno)));
+ return false;
+ }
++#endif
+
+ SetSIStandard(si_std);
+
+@@ -858,6 +870,7 @@ bool V4LChannel::SetInputAndFormat(int inputNum, QString newFmt)
+
+ if (usingv4l1)
+ {
++#ifdef USING_V4L
+ VERBOSE(VB_CHANNEL, LOC + msg + "(v4l v1)");
+
+ // read in old settings
+@@ -875,8 +888,9 @@ bool V4LChannel::SetInputAndFormat(int inputNum, QString newFmt)
+ {
+ VERBOSE(VB_IMPORTANT, LOC_ERR + msg +
+ "\n\t\t\twhile setting format (v4l v1)" + ENO);
+- }
+- else if (usingv4l2)
++ } else
++#endif
++ if (usingv4l2)
+ {
+ VERBOSE(VB_IMPORTANT, LOC + msg +
+ "\n\t\t\tSetting video mode with v4l version 1 worked");
+@@ -951,6 +965,7 @@ bool V4LChannel::SwitchToInput(int inputnum, bool setstarting)
+ return ok;
+ }
+
++#ifdef USING_V4L
+ static unsigned short *get_v4l1_field(
+ int v4l2_attrib, struct video_picture &vid_pic)
+ {
+@@ -970,6 +985,7 @@ static unsigned short *get_v4l1_field(
+ }
+ return NULL;
+ }
++#endif
+
+ static int get_v4l2_attribute(const QString &db_col_name)
+ {
+@@ -1067,6 +1083,7 @@ bool V4LChannel::InitPictureAttribute(const QString db_col_name)
+ }
+
+ // V4L1
++#ifdef USING_V4L
+ unsigned short *setfield;
+ struct video_picture vid_pic;
+ bzero(&vid_pic, sizeof(vid_pic));
+@@ -1087,7 +1104,7 @@ bool V4LChannel::InitPictureAttribute(const QString db_col_name)
+ VERBOSE(VB_IMPORTANT, loc_err + "failed to set controls." + ENO);
+ return false;
+ }
+-
++#endif
+ return true;
+ }
+
+@@ -1154,6 +1171,7 @@ static int get_v4l2_attribute_value(int videofd, int v4l2_attrib)
+
+ static int get_v4l1_attribute_value(int videofd, int v4l2_attrib)
+ {
++#ifdef USING_V4L
+ struct video_picture vid_pic;
+ bzero(&vid_pic, sizeof(vid_pic));
+
+@@ -1167,6 +1185,7 @@ static int get_v4l1_attribute_value(int videofd, int v4l2_attrib)
+ unsigned short *setfield = get_v4l1_field(v4l2_attrib, vid_pic);
+ if (setfield)
+ return *setfield;
++#endif
+
+ return -1;
+ }
+@@ -1210,6 +1229,7 @@ static int set_v4l2_attribute_value(int videofd, int v4l2_attrib, int newvalue)
+
+ static int set_v4l1_attribute_value(int videofd, int v4l2_attrib, int newvalue)
+ {
++#ifdef USING_V4L
+ unsigned short *setfield;
+ struct video_picture vid_pic;
+ bzero(&vid_pic, sizeof(vid_pic));
+@@ -1236,7 +1256,7 @@ static int set_v4l1_attribute_value(int videofd, int v4l2_attrib, int newvalue)
+ // ???
+ return -1;
+ }
+-
++#endif
+ return 0;
+ }
+
+diff --git a/mythtv/libs/libmythtv/v4lchannel.h b/mythtv/libs/libmythtv/v4lchannel.h
+index b059c64..aa6d934 100644
+--- a/mythtv/libs/libmythtv/v4lchannel.h
++++ b/mythtv/libs/libmythtv/v4lchannel.h
+@@ -4,11 +4,11 @@
+ #define CHANNEL_H
+
+ #include "dtvchannel.h"
+-#ifdef USING_V4L
++#ifdef USING_V4L2
+ #include <linux/videodev2.h> // needed for v4l2_std_id type
+ #else
+ typedef uint64_t v4l2_std_id;
+-#endif //USING_V4L
++#endif //USING_V4L2
+
+ using namespace std;
+
+diff --git a/mythtv/libs/libmythtv/vbitext/vbi.c b/mythtv/libs/libmythtv/vbitext/vbi.c
+index 15f8d85..4c50e8d 100644
+--- a/mythtv/libs/libmythtv/vbitext/vbi.c
++++ b/mythtv/libs/libmythtv/vbitext/vbi.c
+@@ -14,8 +14,12 @@
+ // compiling with -std=c99. We could remove this in the .pro file,
+ // but that would disable it for all .c files.
+ #undef __STRICT_ANSI__
++#ifdef USING_V4L
+ #include <linux/videodev.h>
++#endif
++#ifdef USING_V4L2
+ #include <linux/videodev2.h>
++#endif
+
+ // vbitext headers
+ #include "vt.h"
+@@ -29,8 +33,13 @@ static int rawbuf_size; // its current size
+
+
+ /***** bttv api *****/
++#ifdef USING_V4L
+ #define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int)
+-
++#else // !USING_V4L
++#ifdef USING_V4L2
++#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOC_PRIVATE+8, int)
++#endif // USING_V4L2
++#endif // !USING_V4L
+
+ static void
+ error(const char *str, ...)
+diff --git a/mythtv/libs/libmythtv/videosource.cpp b/mythtv/libs/libmythtv/videosource.cpp
+index 5d7a508..635faeb 100644
+--- a/mythtv/libs/libmythtv/videosource.cpp
++++ b/mythtv/libs/libmythtv/videosource.cpp
+@@ -45,7 +45,7 @@ using namespace std;
+ #include "dvbtypes.h"
+ #endif
+
+-#ifdef USING_V4L
++#ifdef USING_V4L2
+ #include <linux/videodev2.h>
+ #endif
+
+@@ -2012,7 +2012,7 @@ CaptureCardGroup::CaptureCardGroup(CaptureCard &parent) :
+ setTrigger(cardtype);
+ setSaveAll(false);
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ addTarget("V4L", new V4LConfigurationGroup(parent));
+ # ifdef USING_IVTV
+ addTarget("MPEG", new MPEGConfigurationGroup(parent));
+@@ -2020,7 +2020,7 @@ CaptureCardGroup::CaptureCardGroup(CaptureCard &parent) :
+ # ifdef USING_HDPVR
+ addTarget("HDPVR", new HDPVRConfigurationGroup(parent));
+ # endif // USING_HDPVR
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+
+ #ifdef USING_DVB
+ addTarget("DVB", new DVBConfigurationGroup(parent));
+@@ -2201,7 +2201,7 @@ CardType::CardType(const CaptureCard &parent) :
+
+ void CardType::fillSelections(SelectSetting* setting)
+ {
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ setting->addSelection(
+ QObject::tr("Analog V4L capture card"), "V4L");
+ setting->addSelection(
+@@ -2214,7 +2214,7 @@ void CardType::fillSelections(SelectSetting* setting)
+ setting->addSelection(
+ QObject::tr("H.264 encoder card (HD-PVR)"), "HDPVR");
+ # endif // USING_HDPVR
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+
+ #ifdef USING_DVB
+ setting->addSelection(
+@@ -2226,11 +2226,11 @@ void CardType::fillSelections(SelectSetting* setting)
+ QObject::tr("FireWire cable box"), "FIREWIRE");
+ #endif // USING_FIREWIRE
+
+-#ifdef USING_V4L
++#if defined(USING_V4L) || defined(USING_V4L2)
+ setting->addSelection(
+ QObject::tr("USB MPEG-4 encoder box (Plextor ConvertX, etc)"),
+ "GO7007");
+-#endif // USING_V4L
++#endif // USING_V4L || USING_V4L2
+
+ #ifdef USING_HDHOMERUN
+ setting->addSelection(
diff --git a/community/qtractor/PKGBUILD b/community/qtractor/PKGBUILD
index b77d264f0..5396ea5d9 100644
--- a/community/qtractor/PKGBUILD
+++ b/community/qtractor/PKGBUILD
@@ -1,9 +1,9 @@
-# $Id: PKGBUILD 37890 2011-01-18 22:57:48Z schiv $
+# $Id: PKGBUILD 48203 2011-05-29 20:38:19Z schiv $
# Maintainer: Ray Rashif <schiv@archlinux.org>
# Contributor: Philipp Überbacher <hollunder at gmx dot at>
pkgname=qtractor
-pkgver=0.4.8
+pkgver=0.4.9
pkgrel=1
pkgdesc="Audio/MIDI multitrack sequencer"
arch=('i686' 'x86_64' 'mips64el')
@@ -15,7 +15,7 @@ makedepends=('ladspa' 'dssi')
[ "$CARCH" = "i686" ] && optdepends=('dssi-vst: win32 VST support')
changelog=$pkgname.changelog
source=(http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz)
-md5sums=('fef232ad6c3312e5af179cdcd2c395ae')
+md5sums=('0d7d8c8783dd29f3cd4ceee16ff38333')
build() {
cd "$srcdir/$pkgname-$pkgver"
diff --git a/community/qtractor/qtractor.changelog b/community/qtractor/qtractor.changelog
index 42d7c31d2..c0c8a8e0c 100644
--- a/community/qtractor/qtractor.changelog
+++ b/community/qtractor/qtractor.changelog
@@ -1,33 +1,3 @@
-19 Jan 2011 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.4.8-1
- upstream release
-
-01 Oct 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.4.7-1
- upstream release
-
-22 May 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.4.6-1
- upstream bug-fix release
-
-24 Jan 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.4.5-2 (testing)
- rebuild against testing/libpng-1.4.0-1
-
-24 Jan 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.4.5-1
- upstream update
-
-21 Jan 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.4.4-2 (testing)
- rebuild against testing/libpng-1.4.0-1
-
17 Jan 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
* 0.4.4-1
@@ -41,3 +11,4 @@
* 0.4.3-1
initial commit
+ only important changes will be logged
diff --git a/core/openvpn/PKGBUILD b/core/openvpn/PKGBUILD
index 2d0c675e1..da36b6c63 100644
--- a/core/openvpn/PKGBUILD
+++ b/core/openvpn/PKGBUILD
@@ -1,8 +1,8 @@
-# $Id: PKGBUILD 98730 2010-11-13 13:55:32Z thomas $
+# $Id: PKGBUILD 123913 2011-05-14 10:10:30Z thomas $
# Maintainer: Thomas Bächler <thomas@archlinux.org>
pkgname=openvpn
-pkgver=2.1.4
+pkgver=2.2.0
pkgrel=1
pkgdesc="An easy-to-use, robust, and highly configurable VPN (Virtual Private Network)"
arch=(i686 x86_64 'mips64el')
@@ -16,7 +16,7 @@ source=(http://swupdate.openvpn.net/community/releases/openvpn-${pkgver}.tar.gz
openvpn.rc
openvpn-tapdev.rc
openvpn-tapdev.conf)
-md5sums=('96a11868082685802489254f03ff3bde'
+md5sums=('4f440603eac45fec7be218b87d570834'
'a3809b9727f0c2af2d0770f5c7442db2'
'd2c48e970088d679dd3c2afd914ff731'
'722f483c9e3ce2ec66d3301aaf7cf3d5')
diff --git a/extra/bluez/PKGBUILD b/extra/bluez/PKGBUILD
index 5978c8b5e..2438b81ae 100644
--- a/extra/bluez/PKGBUILD
+++ b/extra/bluez/PKGBUILD
@@ -1,10 +1,10 @@
-# $Id: PKGBUILD 122436 2011-05-04 06:56:54Z andrea $
+# $Id: PKGBUILD 125758 2011-05-29 12:01:04Z andrea $
# Maintainer: Andrea Scarpino <andrea@archlinux.org>
# Contributor: Geoffroy Carrier <geoffroy@archlinux.org>
pkgname=bluez
pkgver=4.93
-pkgrel=1
+pkgrel=2
pkgdesc="Libraries and tools for the Bluetooth protocol stack"
url="http://www.bluez.org/"
arch=('i686' 'x86_64' 'mips64el')
@@ -49,7 +49,7 @@ build() {
--enable-pand \
--enable-dund \
--enable-cups \
- --disable-udevrules \
+ --enable-udevrules \
--enable-configfiles
make
}
@@ -73,4 +73,7 @@ package() {
install -Dm755 test/simple-agent ${pkgdir}/usr/bin/bluez-simple-agent
sed -i 's#/usr/bin/python#/usr/bin/python2#' \
${pkgdir}/usr/bin/bluez-simple-agent
+
+ # http://mailman.archlinux.org/pipermail/arch-general/2011-April/019787.html
+ rm "${pkgdir}"/lib/udev/rules.d/97-bluetooth.rules
}
diff --git a/extra/jack/PKGBUILD b/extra/jack/PKGBUILD
index f2f5f2f2d..b01ab7191 100644
--- a/extra/jack/PKGBUILD
+++ b/extra/jack/PKGBUILD
@@ -1,11 +1,11 @@
-# $Id: PKGBUILD 112020 2011-03-03 07:49:00Z schiv $
+# $Id: PKGBUILD 125794 2011-05-29 20:29:19Z schiv $
# Maintainer: Ray Rashif <schiv@archlinux.org>
# Contributor: tobias <tobias@archlinux.net>
# Contributor: Robert Emil Berge <robert@rebi.no>
pkgname=jack
_longname=jack-audio-connection-kit
-pkgver=0.120.1
+pkgver=0.120.2
pkgrel=1
pkgdesc="A low-latency audio server"
arch=('i686' 'x86_64' 'mips64el')
@@ -19,7 +19,7 @@ provides=("$_longname=$pkgver")
replaces=("$_longname")
changelog=$pkgname.changelog
source=("http://jackaudio.org/downloads/$_longname-$pkgver.tar.gz")
-md5sums=('e45bab906be64e4e2752cbd855a8efd5')
+md5sums=('21f453676bfb9cb63a3df7e19546f0ed')
build() {
cd "$srcdir/$_longname-$pkgver"
diff --git a/extra/jack/jack.changelog b/extra/jack/jack.changelog
index 04c0c73ec..4c3533694 100644
--- a/extra/jack/jack.changelog
+++ b/extra/jack/jack.changelog
@@ -1,8 +1,3 @@
-3 Mar 2011 (GMT+8) Ray Rashif <schiv@archlinux.org>
-
- * 0.120.1-1:
- Upstream release
-
8 Aug 2010 (GMT+8) Ray Rashif <schiv@archlinux.org>
* 0.118.0-4 :
@@ -17,3 +12,4 @@
* jack.changelog :
Added this changelog.
+ Only important things will be logged.
diff --git a/extra/pango/PKGBUILD b/extra/pango/PKGBUILD
index d5356b6e7..7f74f7683 100644
--- a/extra/pango/PKGBUILD
+++ b/extra/pango/PKGBUILD
@@ -1,9 +1,9 @@
-# $Id: PKGBUILD 118487 2011-04-07 10:59:52Z ibiru $
+# $Id: PKGBUILD 125763 2011-05-29 12:16:06Z ibiru $
# Maintainer: Jan de Groot <jgc@archlinux.org>
pkgname=pango
pkgver=1.28.4
-pkgrel=2
+pkgrel=3
pkgdesc="A library for layout and rendering of text"
arch=('i686' 'x86_64' 'mips64el')
license=('LGPL')
diff --git a/extra/pyalpm/PKGBUILD b/extra/pyalpm/PKGBUILD
new file mode 100644
index 000000000..0db22e4d7
--- /dev/null
+++ b/extra/pyalpm/PKGBUILD
@@ -0,0 +1,23 @@
+# Maintainer : Rémy Oudompheng <remy@archlinux.org>
+
+pkgname=pyalpm
+pkgver=0.4.2
+pkgrel=1
+pkgdesc="Libalpm bindings for Python 3"
+arch=('i686' 'x86_64')
+url="http://projects.archlinux.org/users/remy/pyalpm.git/"
+license=('GPL')
+depends=('python>=3.2' 'pacman<3.6')
+source=("ftp://ftp.archlinux.org/other/pyalpm/$pkgname-$pkgver.tar.gz")
+md5sums=('d5d45cafa98050a4d3c77e4a8f597ff3')
+
+build() {
+ cd ${srcdir}/${pkgname}-${pkgver}
+ python setup.py build
+}
+
+package() {
+ cd ${srcdir}/${pkgname}-${pkgver}
+ python setup.py install --root=${pkgdir}
+}
+
diff --git a/extra/telepathy-logger/PKGBUILD b/extra/telepathy-logger/PKGBUILD
index cdf1d757b..38b399256 100644
--- a/extra/telepathy-logger/PKGBUILD
+++ b/extra/telepathy-logger/PKGBUILD
@@ -1,7 +1,7 @@
-# $Id: PKGBUILD 123372 2011-05-10 16:32:52Z ibiru $
+# $Id: PKGBUILD 125768 2011-05-29 12:37:27Z ibiru $
# Maintainer: Ionut Biru <ibiru@archlinux.org>
pkgname=telepathy-logger
-pkgver=0.2.9
+pkgver=0.2.10
pkgrel=1
pkgdesc="Telepathy framework logging daemon"
arch=(i686 x86_64 'mips64el')
@@ -11,7 +11,7 @@ depends=('telepathy-glib' 'sqlite3' 'libxml2' 'dconf')
makedepends=('intltool' 'gnome-doc-utils' 'gobject-introspection')
options=('!libtool')
source=(http://telepathy.freedesktop.org/releases/${pkgname}/${pkgname}-${pkgver}.tar.bz2)
-md5sums=('6d4a1c916883e4d1f19ed1002be6700c')
+md5sums=('ec01a8f99fc11406e85153095433c155')
build() {
cd "$srcdir/$pkgname-$pkgver"
diff --git a/extra/thunar/PKGBUILD b/extra/thunar/PKGBUILD
index f4d09bafc..d8494a12c 100644
--- a/extra/thunar/PKGBUILD
+++ b/extra/thunar/PKGBUILD
@@ -1,10 +1,10 @@
-# $Id: PKGBUILD 112910 2011-03-07 18:29:57Z andyrtr $
+# $Id: PKGBUILD 125778 2011-05-29 16:38:52Z andyrtr $
# Maintainer: andyrtr <andyrtr funnychar archlinux.org>
# Contributor: Andrew Simmons <andrew.simmons@gmail.com>
pkgname=thunar
-pkgver=1.2.1
-pkgrel=2
+pkgver=1.2.2
+pkgrel=1
pkgdesc="modern file manager for Xfce"
arch=('i686' 'x86_64' 'mips64el')
license=('GPL2' 'LGPL2.1')
@@ -24,7 +24,7 @@ install=${pkgname}.install
backup=('etc/polkit-1/localauthority/50-local.d/org.freedesktop.udisks.pkla')
source=(http://archive.xfce.org/src/xfce/${pkgname}/1.2/Thunar-${pkgver}.tar.bz2
org.freedesktop.udisks.pkla)
-md5sums=('d8dce796890619d67aed0cd7ef84c7b1'
+md5sums=('a86df0212db71e61f459bda6bc7b7fb6'
'a7ddb5eec02d9a8e91a2997862e73cd8')
build() {
diff --git a/extra/v4l-utils/PKGBUILD b/extra/v4l-utils/PKGBUILD
index 2e87f95eb..8a176f2bf 100644
--- a/extra/v4l-utils/PKGBUILD
+++ b/extra/v4l-utils/PKGBUILD
@@ -1,8 +1,8 @@
-# $Id: PKGBUILD 111480 2011-02-27 10:18:47Z thomas $
+# $Id: PKGBUILD 125773 2011-05-29 13:34:22Z thomas $
# Maintainer: Thomas Bächler <thomas@archlinux.org>
pkgname=v4l-utils
pkgver=0.8.3
-pkgrel=1
+pkgrel=2
pkgdesc="Userspace tools and conversion library for Video 4 Linux"
arch=('i686' 'x86_64' 'mips64el')
url="http://freshmeat.net/projects/libv4l"
@@ -28,4 +28,7 @@ package() {
cd "${srcdir}/${pkgname}-${pkgver}"
make install PREFIX="/usr" DESTDIR="${pkgdir}/"
rm -f "${pkgdir}/usr/bin/ivtv-ctl"
+ # Fix udev rule location
+ mkdir -p "${pkgdir}/lib"
+ mv "${pkgdir}/etc/udev" "${pkgdir}/lib"
}
diff --git a/extra/xfce4-sensors-plugin/PKGBUILD b/extra/xfce4-sensors-plugin/PKGBUILD
index 39b1c6e9c..9b54c03f4 100644
--- a/extra/xfce4-sensors-plugin/PKGBUILD
+++ b/extra/xfce4-sensors-plugin/PKGBUILD
@@ -1,9 +1,9 @@
-# $Id: PKGBUILD 123665 2011-05-12 08:18:26Z andyrtr $
+# $Id: PKGBUILD 125783 2011-05-29 16:48:03Z andyrtr $
# Maintainer: Andreas Radke <andyrtr@archlinux.org>
# Contributor: Merk Matthias <macem@chello.at>
pkgname=xfce4-sensors-plugin
-pkgver=1.2.1
+pkgver=1.2.3
pkgrel=1
pkgdesc="A lm_sensors plugin for the Xfce panel"
arch=('i686' 'x86_64' 'mips64el')
@@ -15,19 +15,11 @@ makedepends=('pkgconfig' 'intltool' 'hddtemp>=0.3.beta15.45-2' 'gnu-netcat' 'xfc
optdepends=('gnu-netcat: for hddtemp access')
options=(!libtool !makeflags)
install=${pkgname}.install
-source=(http://archive.xfce.org/src/panel-plugins/${pkgname}/1.2/${pkgname}-${pkgver}.tar.bz2
- git.patch)
-md5sums=('3fd270762d69eb281594bdf16be924b9'
- '181df53dc5bb647274293f72f73ef39b')
+source=(http://archive.xfce.org/src/panel-plugins/${pkgname}/1.2/${pkgname}-${pkgver}.tar.bz2)
+md5sums=('2edf376d140449ca42c4e4f591e626f8')
build() {
cd ${srcdir}/${pkgname}-${pkgver}
- # panel 4.8 patch from http://bugzilla.xfce.org/show_bug.cgi?id=7095
-# patch -Np1 -i ${srcdir}/xfce4-sensors-plugin-1.0.0-underlink.patch
-
-# patch -Np1 -i ${srcdir}/xfce4-sensors-plugin-1.0.0-libnotify-0.7.patch
- patch -Np1 -i ${srcdir}/git.patch
- #xdt-autogen
./configure --prefix=/usr \
--sysconfdir=/etc \
--libexecdir=/usr/lib \
diff --git a/extra/xfdesktop/PKGBUILD b/extra/xfdesktop/PKGBUILD
index 07a5ad402..8c039765c 100644
--- a/extra/xfdesktop/PKGBUILD
+++ b/extra/xfdesktop/PKGBUILD
@@ -1,17 +1,17 @@
-# $Id: PKGBUILD 120363 2011-04-22 18:39:32Z andyrtr $
+# $Id: PKGBUILD 125789 2011-05-29 16:59:08Z andyrtr $
# Maintainer: AndyRTR <andyrtr@archlinux.org>
# Contributor: tobias <tobias funnychar archlinux.org>
pkgname=xfdesktop
pkgver=4.8.2
-pkgrel=1
+pkgrel=2
pkgdesc="A desktop manager for Xfce"
arch=('i686' 'x86_64' 'mips64el')
license=('GPL2')
url="http://www.xfce.org/"
groups=('xfce4')
-depends=('libxfce4ui' 'thunar>=1.2.0' 'hicolor-icon-theme' 'libwnck>=2.30.0')
-makedepends=("xfce4-panel>=4.8.0" 'intltool')
+depends=('libxfce4ui' 'thunar>=1.2.0' 'garcon' 'hicolor-icon-theme' 'libwnck>=2.30.0')
+makedepends=('intltool' 'xfce4-panel>=4.8.0')
optdepends=('xfce4-panel: panel menu plugin')
conflicts=('xfce4-menueditor')
replaces=('xfce4-menueditor')
@@ -22,8 +22,6 @@ md5sums=('ed25d59f478afda552d121e96657d16f')
build() {
cd "${srcdir}/${pkgname}-${pkgver}"
- # git fixes
-
./configure --prefix=/usr \
--sysconfdir=/etc \
--libexecdir=/usr/lib \
diff --git a/testing/re-alpine/PKGBUILD b/testing/re-alpine/PKGBUILD
new file mode 100644
index 000000000..9293744c9
--- /dev/null
+++ b/testing/re-alpine/PKGBUILD
@@ -0,0 +1,38 @@
+# $Id: PKGBUILD 125747 2011-05-29 05:24:41Z eric $
+# Maintainer: Eric Bélanger <eric@archlinux.org>
+# Contributor: Smith Dhumbumroong <zodmaner@gmail.com>
+
+pkgname=re-alpine
+pkgver=2.02
+pkgrel=3
+pkgdesc="The continuation of the Alpine email client from University of Washington"
+arch=('i686' 'x86_64')
+url="http://sourceforge.net/projects/re-alpine/"
+license=('APACHE')
+depends=('libldap' 'krb5')
+optdepends=('aspell: spell-checking support'
+ 'hunspell: spell-checking support')
+provides=('pine' 'alpine')
+conflicts=('pine' 'alpine')
+replaces=('pine' 'alpine')
+options=('!makeflags')
+source=(http://downloads.sourceforge.net/project/re-alpine/${pkgname}-${pkgver}.tar.bz2
+ maildir.patch)
+md5sums=('5e75826b15f05674856be8618bdefdfb'
+ '8d7a0e8d940e84e978f50266405c7361')
+sha1sums=('9c2f13dbc7ca75e7a09f81df607db84694b10fa6'
+ 'c09a8e42f9dba3e63a3755a9c418af95da721d8d')
+
+build() {
+ cd "${srcdir}/${pkgname}-${pkgver}"
+ patch -p1 < ../maildir.patch
+ LIBS+=-lpam ./configure --prefix=/usr --without-passfile --without-tcl \
+ --disable-shared --with-system-pinerc=/etc/alpine.d/pine.conf \
+ --with-system-fixed-pinerc=/etc/alpine.d/pine.conf.fixed
+ make
+}
+
+package() {
+ cd "${srcdir}/${pkgname}-${pkgver}"
+ make DESTDIR="${pkgdir}" install
+}
diff --git a/testing/re-alpine/maildir.patch b/testing/re-alpine/maildir.patch
new file mode 100644
index 000000000..cff18cb3f
--- /dev/null
+++ b/testing/re-alpine/maildir.patch
@@ -0,0 +1,3712 @@
+diff -rc alpine-2.00/alpine/alpine.c alpine-2.00.maildir/alpine/alpine.c
+*** alpine-2.00/alpine/alpine.c 2008-06-03 17:31:05.000000000 -0500
+--- alpine-2.00.maildir/alpine/alpine.c 2011-01-15 19:11:06.000000000 -0600
+***************
+*** 553,558 ****
+--- 553,563 ----
+ if(F_ON(F_MAILDROPS_PRESERVE_STATE, ps_global))
+ mail_parameters(NULL, SET_SNARFPRESERVE, (void *) TRUE);
+
++ #ifndef _WINDOWS
++ mail_parameters(NULL,SET_COURIERSTYLE,
++ (void *)(F_ON(F_COURIER_FOLDER_LIST, ps_global) ? 1 : 0));
++ #endif
++
+ rvl = 0L;
+ if(pine_state->VAR_NNTPRANGE){
+ if(!SVAR_NNTPRANGE(pine_state, rvl, tmp_20k_buf, SIZEOF_20KBUF))
+diff -rc alpine-2.00/alpine/confscroll.c alpine-2.00.maildir/alpine/confscroll.c
+*** alpine-2.00/alpine/confscroll.c 2008-08-21 17:14:45.000000000 -0500
+--- alpine-2.00.maildir/alpine/confscroll.c 2011-01-15 19:11:06.000000000 -0600
+***************
+*** 5489,5494 ****
+--- 5489,5500 ----
+ (void *)var->current_val.p);
+ }
+ #endif
++ #ifndef _WINDOWS
++ else if(var == &ps->vars[V_MAILDIR_LOCATION]){
++ if(var->current_val.p && var->current_val.p[0])
++ mail_parameters(NULL, SET_MDINBOXPATH, (void *)var->current_val.p);
++ }
++ #endif
+ else if(revert && standard_radio_var(ps, var)){
+
+ cur_rule_value(var, TRUE, FALSE);
+diff -rc alpine-2.00/imap/src/c-client/mail.c alpine-2.00.maildir/imap/src/c-client/mail.c
+*** alpine-2.00/imap/src/c-client/mail.c 2008-06-04 13:39:54.000000000 -0500
+--- alpine-2.00.maildir/imap/src/c-client/mail.c 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 991,997 ****
+ MAILSTREAM *ts;
+ char *s,*t,tmp[MAILTMPLEN];
+ size_t i;
+! DRIVER *d;
+ /* never allow names with newlines */
+ if (s = strpbrk (mailbox,"\015\012")) {
+ MM_LOG ("Can't create mailbox with such a name",ERROR);
+--- 991,997 ----
+ MAILSTREAM *ts;
+ char *s,*t,tmp[MAILTMPLEN];
+ size_t i;
+! DRIVER *d, *md;
+ /* never allow names with newlines */
+ if (s = strpbrk (mailbox,"\015\012")) {
+ MM_LOG ("Can't create mailbox with such a name",ERROR);
+***************
+*** 1015,1020 ****
+--- 1015,1022 ----
+ return NIL;
+ }
+
++ /* Hack, we should do this better, but it works */
++ for (md = maildrivers; md && strcmp (md->name, "md"); md = md->next);
+ /* see if special driver hack */
+ if ((mailbox[0] == '#') && ((mailbox[1] == 'd') || (mailbox[1] == 'D')) &&
+ ((mailbox[2] == 'r') || (mailbox[2] == 'R')) &&
+***************
+*** 1045,1050 ****
+--- 1047,1059 ----
+ (((*mailbox == '{') || (*mailbox == '#')) &&
+ (stream = mail_open (NIL,mailbox,OP_PROTOTYPE | OP_SILENT))))
+ d = stream->dtb;
++ else if(mailbox[0] == '#'
++ && (mailbox[1] == 'm' || mailbox[1] == 'M')
++ && (mailbox[2] == 'd' || mailbox[2] == 'D'
++ || mailbox[2] == 'c' || mailbox[2] == 'C')
++ && mailbox[3] == '/'
++ && mailbox[4] != '\0')
++ return (*md->create)(stream, mailbox);
+ else if ((*mailbox != '{') && (ts = default_proto (NIL))) d = ts->dtb;
+ else { /* failed utterly */
+ sprintf (tmp,"Can't create mailbox %.80s: indeterminate format",mailbox);
+diff -rc alpine-2.00/imap/src/c-client/mail.h alpine-2.00.maildir/imap/src/c-client/mail.h
+*** alpine-2.00/imap/src/c-client/mail.h 2008-08-08 12:34:22.000000000 -0500
+--- alpine-2.00.maildir/imap/src/c-client/mail.h 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 353,358 ****
+--- 353,362 ----
+ #define SET_SCANCONTENTS (long) 573
+ #define GET_MHALLOWINBOX (long) 574
+ #define SET_MHALLOWINBOX (long) 575
++ #define GET_COURIERSTYLE (long) 576
++ #define SET_COURIERSTYLE (long) 577
++ #define SET_MDINBOXPATH (long) 578
++ #define GET_MDINBOXPATH (long) 579
+
+ /* Driver flags */
+
+diff -rc alpine-2.00/imap/src/osdep/unix/dummy.c alpine-2.00.maildir/imap/src/osdep/unix/dummy.c
+*** alpine-2.00/imap/src/osdep/unix/dummy.c 2008-06-04 13:18:34.000000000 -0500
+--- alpine-2.00.maildir/imap/src/osdep/unix/dummy.c 2011-01-15 20:01:59.000000000 -0600
+***************
+*** 106,118 ****
+ * Accepts: mailbox name
+ * Returns: our driver if name is valid, NIL otherwise
+ */
+!
+ DRIVER *dummy_valid (char *name)
+ {
+! char *s,tmp[MAILTMPLEN];
+ struct stat sbuf;
+ /* must be valid local mailbox */
+! if (name && *name && (*name != '{') && (s = mailboxfile (tmp,name))) {
+ /* indeterminate clearbox INBOX */
+ if (!*s) return &dummydriver;
+ else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {
+--- 106,124 ----
+ * Accepts: mailbox name
+ * Returns: our driver if name is valid, NIL otherwise
+ */
+! char * maildir_remove_root(char *);
+ DRIVER *dummy_valid (char *name)
+ {
+! char *s,tmp[MAILTMPLEN], *rname;
+ struct stat sbuf;
++
++ if(strlen(name) > MAILTMPLEN)
++ name[MAILTMPLEN] = '\0';
++
++ strcpy(tmp, name);
++ rname = maildir_remove_root(tmp);
+ /* must be valid local mailbox */
+! if (rname && *rname && (*rname != '{') && (s = mailboxfile (tmp,rname))) {
+ /* indeterminate clearbox INBOX */
+ if (!*s) return &dummydriver;
+ else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {
+***************
+*** 121,128 ****
+ return &dummydriver;
+ }
+ /* blackbox INBOX does not exist yet */
+! else if (!compare_cstring (name,"INBOX")) return &dummydriver;
+ }
+ return NIL;
+ }
+
+--- 127,135 ----
+ return &dummydriver;
+ }
+ /* blackbox INBOX does not exist yet */
+! else if (!compare_cstring (rname,"INBOX")) return &dummydriver;
+ }
++ if(rname) fs_give((void **)&rname);
+ return NIL;
+ }
+
+***************
+*** 454,459 ****
+--- 461,468 ----
+ {
+ char *s,tmp[MAILTMPLEN];
+ long ret = NIL;
++ if(!strncmp(mailbox,"#md/",4) || !strncmp(mailbox,"#mc/", 4))
++ return maildir_create(stream, mailbox);
+ /* validate name */
+ if (!(compare_cstring (mailbox,"INBOX") && (s = dummy_file (tmp,mailbox)))) {
+ sprintf (tmp,"Can't create %.80s: invalid name",mailbox);
+***************
+*** 519,524 ****
+--- 528,541 ----
+ {
+ struct stat sbuf;
+ char *s,tmp[MAILTMPLEN];
++ if (!strncmp(mailbox,"#md/",4) || !strncmp(mailbox,"#mc/", 4)
++ || is_valid_maildir(&mailbox)){
++ char tmp[MAILTMPLEN] = {'\0'};
++ strcpy(tmp, mailbox);
++ if(tmp[strlen(tmp) - 1] != '/')
++ tmp[strlen(tmp)] = '/';
++ return maildir_delete(stream, tmp);
++ }
+ if (!(s = dummy_file (tmp,mailbox))) {
+ sprintf (tmp,"Can't delete - invalid name: %.80s",s);
+ MM_LOG (tmp,ERROR);
+***************
+*** 544,555 ****
+ long dummy_rename (MAILSTREAM *stream,char *old,char *newname)
+ {
+ struct stat sbuf;
+! char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN];
+ /* no trailing / allowed */
+! if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) ||
+ stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] &&
+ ((sbuf.st_mode & S_IFMT) != S_IFDIR))) {
+! sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",old,newname);
+ MM_LOG (mbx,ERROR);
+ return NIL;
+ }
+--- 561,583 ----
+ long dummy_rename (MAILSTREAM *stream,char *old,char *newname)
+ {
+ struct stat sbuf;
+! char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN], *rold, *rnewname;
+!
+! if(strlen(old) > MAILTMPLEN)
+! old[MAILTMPLEN] = '\0';
+!
+! if(strlen(newname) > MAILTMPLEN)
+! newname[MAILTMPLEN] = '\0';
+!
+! strcpy(tmp, old);
+! rold = maildir_remove_root(tmp);
+! strcpy(tmp, newname);
+! rnewname = maildir_remove_root(tmp);
+ /* no trailing / allowed */
+! if (!dummy_file (oldname,rold) || !(s = dummy_file (mbx,rnewname)) ||
+ stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] &&
+ ((sbuf.st_mode & S_IFMT) != S_IFDIR))) {
+! sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",rold,rnewname);
+ MM_LOG (mbx,ERROR);
+ return NIL;
+ }
+***************
+*** 565,578 ****
+ }
+ }
+ /* rename of non-ex INBOX creates dest */
+! if (!compare_cstring (old,"INBOX") && stat (oldname,&sbuf))
+ return dummy_create (NIL,mbx);
+ if (rename (oldname,mbx)) {
+! sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",old,newname,
+ strerror (errno));
+ MM_LOG (tmp,ERROR);
+ return NIL;
+ }
+ return T; /* return success */
+ }
+
+--- 593,608 ----
+ }
+ }
+ /* rename of non-ex INBOX creates dest */
+! if (!compare_cstring (rold,"INBOX") && stat (oldname,&sbuf))
+ return dummy_create (NIL,mbx);
+ if (rename (oldname,mbx)) {
+! sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",rold,rnewname,
+ strerror (errno));
+ MM_LOG (tmp,ERROR);
+ return NIL;
+ }
++ if(rold) fs_give((void **)&rold);
++ if(rnewname) fs_give((void **)&rnewname);
+ return T; /* return success */
+ }
+
+diff -rc alpine-2.00/imap/src/osdep/unix/maildir.c alpine-2.00.maildir/imap/src/osdep/unix/maildir.c
+*** alpine-2.00/imap/src/osdep/unix/maildir.c 2011-01-24 19:38:50.000000000 -0600
+--- alpine-2.00.maildir/imap/src/osdep/unix/maildir.c 2011-01-15 19:38:50.000000000 -0600
+***************
+*** 0 ****
+--- 1,2584 ----
++ /*
++ * Maildir driver for Alpine 2.00
++ *
++ * Written by Eduardo Chappa <chappa@washington.edu>
++ * Last Update: November 6, 2010.
++ *
++ */
++
++ #include <stdio.h>
++ #include <ctype.h>
++ #include <errno.h>
++ extern int errno; /* just in case */
++ #include "mail.h"
++ #include <pwd.h>
++ #include <sys/stat.h>
++ #include <sys/time.h>
++ #include "osdep.h"
++ #include "rfc822.h"
++ #include "fdstring.h"
++ #include "misc.h"
++ #include "dummy.h"
++ #include "maildir.h"
++
++ /* Driver dispatch used by MAIL */
++ DRIVER maildirdriver = {
++ "md", /* driver name, yes it's md, not maildir */
++ /* driver flags */
++ DR_MAIL|DR_LOCAL|DR_NAMESPACE|DR_DIRFMT,
++ (DRIVER *) NIL, /* next driver */
++ maildir_valid, /* mailbox is valid for us */
++ maildir_parameters, /* manipulate parameters */
++ NIL, /* scan mailboxes */
++ maildir_list, /* find mailboxes */
++ maildir_lsub, /* find subscribed mailboxes */
++ maildir_sub, /* subscribe to mailbox */
++ maildir_unsub, /* unsubscribe from mailbox */
++ maildir_create, /* create mailbox */
++ maildir_delete, /* delete mailbox */
++ maildir_rename, /* rename mailbox */
++ mail_status_default, /* status of mailbox */
++ maildir_open, /* open mailbox */
++ maildir_close, /* close mailbox */
++ maildir_fast, /* fetch message "fast" attributes */
++ NIL, /* fetch message flags */
++ NIL, /* fetch overview */
++ NIL, /* fetch message structure */
++ maildir_header, /* fetch message header */
++ maildir_text, /* fetch message body */
++ NIL, /* fetch partial message text */
++ NIL, /* unique identifier */
++ NIL, /* message number */
++ NIL, /* modify flags */
++ maildir_flagmsg, /* per-message modify flags */
++ NIL, /* search for message based on criteria */
++ NIL, /* sort messages */
++ NIL, /* thread messages */
++ maildir_ping, /* ping mailbox to see if still alive */
++ maildir_check, /* check for new messages */
++ maildir_expunge, /* expunge deleted messages */
++ maildir_copy, /* copy messages to another mailbox */
++ maildir_append, /* append string message to mailbox */
++ NIL /* garbage collect stream */
++ };
++
++
++ DRIVER courierdriver = {
++ "mc", /* Why a separate driver? So that
++ createproto will work */
++ /* driver flags */
++ DR_MAIL|DR_LOCAL|DR_NAMESPACE|DR_DIRFMT,
++ (DRIVER *) NIL, /* next driver */
++ maildir_valid, /* mailbox is valid for us */
++ maildir_parameters, /* manipulate parameters */
++ NIL, /* scan mailboxes */
++ courier_list, /* find mailboxes */
++ maildir_lsub, /* find subscribed mailboxes */
++ maildir_sub, /* subscribe to mailbox */
++ maildir_unsub, /* unsubscribe from mailbox */
++ maildir_create, /* create mailbox */
++ maildir_delete, /* delete mailbox */
++ maildir_rename, /* rename mailbox */
++ mail_status_default, /* status of mailbox */
++ maildir_open, /* open mailbox */
++ maildir_close, /* close mailbox */
++ maildir_fast, /* fetch message "fast" attributes */
++ NIL, /* fetch message flags */
++ NIL, /* fetch overview */
++ NIL, /* fetch message structure */
++ maildir_header, /* fetch message header */
++ maildir_text, /* fetch message body */
++ NIL, /* fetch partial message text */
++ NIL, /* unique identifier */
++ NIL, /* message number */
++ NIL, /* modify flags */
++ maildir_flagmsg, /* per-message modify flags */
++ NIL, /* search for message based on criteria */
++ NIL, /* sort messages */
++ NIL, /* thread messages */
++ maildir_ping, /* ping mailbox to see if still alive */
++ maildir_check, /* check for new messages */
++ maildir_expunge, /* expunge deleted messages */
++ maildir_copy, /* copy messages to another mailbox */
++ maildir_append, /* append string message to mailbox */
++ NIL /* garbage collect stream */
++ };
++
++ MAILSTREAM maildirproto = {&maildirdriver}; /* prototype stream */
++ MAILSTREAM courierproto = {&courierdriver}; /* prototype stream */
++
++ long maildir_dirfmttest (char *name)
++ {
++ int i;
++ for (i = 0; mdstruct[i] && strcmp(name, mdstruct[i]); i++);
++ return (i < EndDir) || !strcmp(name, MDDIR)
++ || !strncmp(name, MDUIDLAST, strlen(MDUIDLAST))
++ || !strncmp(name, MDUIDTEMP, strlen(MDUIDTEMP)) ? LONGT : NIL;
++ }
++
++ void
++ md_domain_name(void)
++ {
++ int i;
++
++ strcpy(mdlocaldomain,mylocalhost ());
++ for (i = 0; mdlocaldomain[i] ; i++)
++ if(mdlocaldomain[i] == '/')
++ mdlocaldomain[i] = '\057';
++ else if (mdlocaldomain[i] == ':')
++ mdlocaldomain[i] = '\072';
++ }
++
++ char *
++ myrootdir(char *name)
++ {
++ return myhomedir();
++ }
++
++ char *
++ mdirpath(void)
++ {
++ char *path = maildir_parameters(GET_MDINBOXPATH,NIL);
++ return path ? (path[0] ? path : ".") : "Maildir";
++ }
++
++ /* remove the "#md/" or "#mc/" part from a folder name */
++ char *
++ maildir_remove_root (char *name)
++ {
++ int courier = IS_COURIER(name), offset;
++ char realname[MAILTMPLEN];
++
++ offset = maildir_valid_name(name) ? (name[3] == '/' ? 4 : 3) : 0;
++ if(courier)
++ courier_realname(name+offset, realname);
++ else
++ strcpy(realname, name+offset);
++ return cpystr(realname);
++ }
++
++
++ /* Check validity of the name, we accept:
++ * a) #md/directory/folder
++ * b) #md/inbox
++ * A few considerations: We can only accept as valid
++ * a) names that start with #md/ and the directory exists or
++ * b) names that do not start with #md/ but are maildir directories (have
++ * the /cur, /tmp and /new structure)
++ */
++ int maildir_valid_name (char *name)
++ {
++ char tmpname[MAILTMPLEN] = {'\0'};
++
++ if (mdfpath)
++ fs_give((void **)&mdfpath);
++ if (name && (name[0] != '#'))
++ sprintf(tmpname,"%s%s",MDPREFIX(CCLIENT), name);
++ mdfpath = cpystr(tmpname[0] ? tmpname : name);
++
++ return IS_CCLIENT(name) || IS_COURIER(name);
++ }
++
++ /* Check if the directory whose path is given by name is a valid maildir
++ * directory (contains /cur, /tmp and /new)
++ */
++ int maildir_valid_dir (char *name)
++ {
++ int len;
++ DirNamesType i;
++ struct stat sbuf;
++ char tmp[MAILTMPLEN];
++
++ if(name[strlen(name) - 1] == '/')
++ name[strlen(name) - 1] = '\0';
++ len = strlen(name);
++ for (i = Cur; i != EndDir; i++){
++ MDFLD(tmp, name, i);
++ if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
++ break;
++ }
++ name[len] = '\0';
++ return (i == EndDir) ? T : NIL;
++ }
++
++ void courier_realname(char *name, char *realname)
++ {
++ int i,j;
++
++ if(!name)
++ return;
++
++ for (i = 0, j = 0; i < MAILTMPLEN && j < strlen(name); j++, i++){
++ realname[i] = name[j];
++ if(name[j] == '/' && name[j+1] != '.' && name[j+1] != '%'
++ && name[j+1] != '*')
++ realname[++i] = '.';
++ }
++ if(realname[i-1] == '.')
++ i--;
++ realname[i] = '\0';
++ }
++
++
++ /* given a maildir folder, return its path. Memory freed by caller. Directory
++ * does not contain the trailing slash "/". On error NULL is returned.
++ */
++ int maildir_file_path (char *name, char *tmp)
++ {
++ char *maildirpath = mdirpath(), *rname;
++ int courier = IS_COURIER(name);
++
++ /* There are several ways in which the path can come, so we will handle
++ them here. First we deal with #mc/ or #md/ prefix by removing the
++ prefix, if any */
++
++ if(strlen(name) >= MAILTMPLEN)
++ name[MAILTMPLEN] = '\0';
++ strcpy(tmp, name);
++ rname = maildir_remove_root(tmp);
++ tmp[0] = '\0'; /* just in case something fails */
++
++ if (strlen(myrootdir(rname)) +
++ max(strlen(rname), strlen(maildirpath)) > MAILTMPLEN){
++ errno = ENAMETOOLONG;
++ sprintf(tmp,"Error opening \"%s\": %s", rname, strerror (errno));
++ mm_log(tmp,ERROR);
++ return NIL;
++ }
++
++ /* There are two ways in which the name can come here, either as a
++ full path or not. If it is not a full path it can come in two ways,
++ either as a file system path (Maildir/.Drafts) or as a maildir path
++ (INBOX.Drafts)
++ */
++
++ if(*rname == '/') /* full path */
++ strcpy(tmp, rname); /* do nothing */
++ else{
++ sprintf (tmp,"%s/%s%s%s", myrootdir (rname),
++ strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5)
++ ? rname : maildirpath,
++ strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5)
++ ? "" : (courier ? "/" : ""),
++ strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5)
++ ? "" : (*(rname+5) == MDSEPARATOR(courier) ? rname+5 : ""));
++ }
++ if(rname) fs_give((void **)&rname);
++ return tmp[0] ? T : NIL;
++ }
++
++ /* This function is given a full path for a mailbox and returns
++ * if it is a valid maildir transformed to canonical notation
++ */
++ int
++ is_valid_maildir (char **name)
++ {
++ if (!strncmp(*name, myrootdir (*name), strlen(myrootdir(*name)))){
++ (*name) += strlen(myrootdir(*name));
++ if (**name == '/') (*name)++;
++ }
++ return maildir_valid(*name) ? T : NIL;
++ }
++
++ /* Check validity of mailbox. This routine does not send errors to log, other
++ * routines calling this one may do so, though
++ */
++
++ DRIVER *maildir_valid (char *name)
++ {
++ char tmpname[MAILTMPLEN];
++
++ maildir_file_path(name, tmpname);
++
++ return maildir_valid_dir(tmpname)
++ ? (IS_COURIER(name) ? &courierdriver : &maildirdriver) : NIL;
++ }
++
++ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags)
++ {
++ unsigned long i;
++ MESSAGECACHE *elt;
++ /* get sequence */
++ if (stream && LOCAL && ((flags & FT_UID) ?
++ mail_uid_sequence (stream,sequence) :
++ mail_sequence (stream,sequence)))
++ for (i = 1L; i <= stream->nmsgs; i++) {
++ if ((elt = mail_elt (stream,i))->sequence && (elt->valid = T) &&
++ !(elt->day && elt->rfc822_size)) {
++ ENVELOPE **env = NIL;
++ ENVELOPE *e = NIL;
++ if (!stream->scache) env = &elt->private.msg.env;
++ else if (stream->msgno == i) env = &stream->env;
++ else env = &e;
++ if (!*env || !elt->rfc822_size) {
++ STRING bs;
++ unsigned long hs;
++ char *ht = (*stream->dtb->header) (stream,i,&hs,NIL);
++
++ if (!*env) rfc822_parse_msg (env,NIL,ht,hs,NIL,BADHOST,
++ stream->dtb->flags);
++ if (!elt->rfc822_size) {
++ (*stream->dtb->text) (stream,i,&bs,FT_PEEK);
++ elt->rfc822_size = hs + SIZE (&bs) - GETPOS (&bs);
++ }
++ }
++
++ if (!elt->day && *env && (*env)->date)
++ mail_parse_date (elt,(*env)->date);
++
++ if (!elt->day) elt->day = elt->month = 1;
++ mail_free_envelope (&e);
++ }
++ }
++ }
++
++ int
++ maildir_eliminate_duplicate (char *name, struct direct ***flist, unsigned long *nfiles)
++ {
++ int i, j, k, error = 0, scanr;
++ char new[MAILTMPLEN], old[MAILTMPLEN], tmp[MAILTMPLEN], *str;
++ struct direct **names = NIL;
++
++ if((scanr = maildir_doscandir(name, &names, CCLIENT)) < 0)
++ return -1;
++
++ if(nfiles) *nfiles = scanr;
++ for(i = 0, j = 1, k = 0; j < scanr; i++, j++){
++ if(k)
++ names[i] = names[i+k];
++ if(same_maildir_file(names[i]->d_name, names[j]->d_name)){
++ int d, f, r, s;
++ maildir_getflag(names[i]->d_name, &d, &f, &r, &s, NIL);
++ sprintf(old,"%s/%s", name, names[i]->d_name);
++ sprintf(new,"%s/.%s", name, names[i]->d_name);
++ if(rename(old, new) < 0 && errno != EEXIST)
++ error++;
++ if(!error){
++ for(; j < scanr
++ && same_maildir_file(names[i]->d_name, names[j]->d_name)
++ ; j++, k++){
++ maildir_getflag(names[j]->d_name, (d ? NIL : &d),
++ (f ? NIL : &f), (r ? NIL : &r), (s ? NIL : &s), NIL);
++ sprintf(tmp,"%s/%s", name, names[j]->d_name);
++ if(unlink(tmp) < 0){ /* Hmmm... a problem, let's see */
++ struct stat sbuf;
++ if (stat(tmp, &sbuf) == 0 && (sbuf.st_mode & S_IFMT) == S_IFREG)
++ error++;
++ }
++ }
++ if((str = strrchr(names[i]->d_name,FLAGSEP)) != NULL) *str = '\0';
++ sprintf (old,"%s/%s%s%s%s%s%s", name, names[i]->d_name, MDSEP(2),
++ MDFLAG(Draft, d), MDFLAG(Flagged, f), MDFLAG(Replied, r),
++ MDFLAG(Seen, s));
++ if(rename(new, old) < 0)
++ error++;
++ }
++ }
++
++ }
++ if(k > 0)
++ fs_give((void **)&names);
++ else
++ *flist = names;
++ return error ? -1 : k;
++ }
++
++ int
++ maildir_doscandir(char *name, struct direct ***flist, int flag)
++ {
++ return scandir(name, flist,
++ flag == CCLIENT ? maildir_select : courier_dir_select,
++ flag == CCLIENT ? maildir_namesort : courier_dir_sort);
++ }
++
++ /*
++ * return all files in a given directory. This is a separate call
++ * so that if there are warnings during compilation this only appears once.
++ */
++ unsigned long
++ maildir_scandir (char *name, struct direct ***flist,
++ unsigned long *nfiles, int *scand, int flag)
++ {
++ struct stat sbuf;
++ int rv = -2; /* impossible value */
++
++ if (scand)
++ *scand = -1; /* assume error for safety */
++ *nfiles = 0;
++ if((stat(name,&sbuf) < 0)
++ || (flag == CCLIENT
++ && ((rv = maildir_eliminate_duplicate(name, flist, nfiles)) < 0)))
++ return 0L;
++
++ if (scand && (rv > 0 || rv == -2))
++ *nfiles = maildir_doscandir(name, flist, flag);
++
++ if(scand) *scand = *nfiles;
++
++ return (unsigned long) sbuf.st_ctime;
++ }
++
++ /* Does a message with given name exists (or was it removed)?
++ * Returns: 1 - yes, such message exist,
++ * 0 - No, that message does not exist anymore
++ *
++ * Parameters: stream, name of mailbox, new name if his message does not
++ * exist.
++ */
++
++ int maildir_message_exists(MAILSTREAM *stream, char *name, char *newfile)
++ {
++ char tmp[MAILTMPLEN];
++ int gotit = NIL;
++ DIR *dir;
++ struct direct *d;
++ struct stat sbuf;
++
++ /* First check directly if it exists, if not there, look for it */
++ sprintf(tmp,"%s/%s", LOCAL->curdir, name);
++ if ((stat(tmp, &sbuf) == 0) && ((sbuf.st_mode & S_IFMT) == S_IFREG))
++ return T;
++
++ if (!(dir = opendir (LOCAL->curdir)))
++ return NIL;
++
++ while ((d = readdir(dir)) && gotit == NIL){
++ if (d->d_name[0] == '.')
++ continue;
++ if (same_maildir_file(d->d_name, name)){
++ gotit = T;
++ strcpy(newfile, d->d_name);
++ }
++ }
++ closedir(dir);
++ return gotit;
++ }
++
++ /* Maildir open */
++
++ MAILSTREAM *maildir_open (MAILSTREAM *stream)
++ {
++ char tmp[MAILTMPLEN];
++ struct stat sbuf;
++
++ if (!stream) return &maildirproto;
++ if (stream->local) fatal ("maildir recycle stream");
++ md_domain_name(); /* get domain name for maildir files in mdlocaldomain */
++ if(mypid == (pid_t) 0)
++ mypid = getpid();
++ if (!stream->rdonly){
++ stream->perm_seen = stream->perm_deleted = stream->perm_flagged =
++ stream->perm_answered = stream->perm_draft = T;
++ }
++ stream->local = (MAILDIRLOCAL *) fs_get (sizeof (MAILDIRLOCAL));
++ memset(LOCAL, 0, sizeof(MAILDIRLOCAL));
++ LOCAL->fd = -1;
++
++ LOCAL->courier = IS_COURIER(stream->mailbox);
++ strcpy(tmp, stream->mailbox);
++ if (maildir_file_path (stream->mailbox, tmp))
++ LOCAL->dir = cpystr (tmp);
++ LOCAL->candouid = maildir_can_assign_uid(stream);
++ maildir_read_uid(stream, &stream->uid_last, &stream->uid_validity);
++ if (LOCAL->dir){
++ MDFLD(tmp, LOCAL->dir, Cur);
++ LOCAL->curdir = cpystr (tmp);
++ if (stat (LOCAL->curdir,&sbuf) < 0) {
++ sprintf (tmp,"Can't open folder %s: %s",
++ stream->mailbox,strerror (errno));
++ mm_log (tmp,ERROR);
++ maildir_close(stream, 0);
++ return NIL;
++ }
++ }
++
++ if(maildir_file_path (stream->mailbox, tmp)){
++ fs_give ((void **) &stream->mailbox);
++ stream->mailbox = cpystr(tmp);
++ }
++
++ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = SENDBUFLEN) + 1);
++ stream->sequence++;
++ stream->nmsgs = stream->recent = 0L;
++
++ maildir_parse_folder(stream, 1);
++
++ return stream;
++ }
++
++ /* Maildir initial parsing of the folder */
++ void
++ maildir_parse_folder (MAILSTREAM *stream, int full)
++ {
++ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN];
++ struct direct **namescur = NIL, **namesnew = NIL;
++ unsigned long i, nfilescur = 0L, nfilesnew = 0L, oldpos, newpos, total;
++ int scan_err, rescan, loop = 0;
++
++ if (!stream) /* what??? */
++ return;
++
++ MM_CRITICAL(stream);
++
++ MDFLD(tmp, LOCAL->dir, New);
++ maildir_scandir (tmp, &namesnew, &nfilesnew, &scan_err, CCLIENT);
++ if (scan_err < 0)
++ maildir_abort(stream);
++
++ /* Scan old messages first, escoba! */
++ if(stream->rdonly ||
++ (LOCAL && ((maildir_initial_check(stream, Cur) == 0)
++ || nfilesnew > 0L))){
++ MDFLD(tmp, LOCAL->dir, Cur);
++ LOCAL->scantime = maildir_scandir (tmp, &namescur, &nfilescur,
++ &scan_err, CCLIENT);
++ if (scan_err < 0){
++ if(namesnew){
++ for(i = 0L; i < nfilesnew; i++)
++ fs_give((void **)&namesnew[i]);
++ fs_give((void **) &namesnew);
++ }
++ maildir_abort(stream);
++ }
++ }
++ if(LOCAL && (maildir_initial_check(stream, New) == 0)
++ && (nfilescur > 0L)){
++ MDFLD(tmp, LOCAL->dir, New);
++ while(LOCAL && loop < 10){
++ if(nfilesnew == 0L)
++ maildir_scandir (tmp, &namesnew, &nfilesnew, &scan_err, CCLIENT);
++ if (scan_err < 0){
++ if(namesnew){
++ for(i = 0L; i < nfilesnew; i++)
++ fs_give((void **)&namesnew[i]);
++ fs_give((void **) &namesnew);
++ }
++ maildir_abort(stream);
++ break;
++ }
++ for(i = 0L, rescan = 0, newpos = oldpos = 0L;
++ newpos < nfilescur && i < nfilesnew; i++){
++ if(maildir_message_in_list(namesnew[i]->d_name, namescur, oldpos,
++ nfilescur - 1L, &newpos)){
++ oldpos = newpos;
++ sprintf(tmp2,"%s/%s",tmp,namesnew[i]->d_name);
++ if(unlink(tmp2) < 0)
++ scan_err = -1;
++ rescan++;
++ }
++ else
++ newpos = oldpos;
++ }
++ if(scan_err < 0)
++ maildir_abort(stream);
++ if(rescan == 0)
++ break;
++ else{ /* restart */
++ if(namesnew){
++ for(i = 0L; i < nfilesnew; i++)
++ fs_give((void **)&namesnew[i]);
++ fs_give((void **) &namesnew);
++ }
++ nfilesnew = 0L;
++ loop++;
++ }
++ }
++ }
++ if(loop == 10)
++ maildir_abort(stream);
++ if(LOCAL){
++ if(stream->rdonly)
++ stream->recent = 0L;
++ total = namescur || stream->rdonly
++ ? maildir_parse_dir(stream, 0L, Cur, namescur,
++ nfilescur, full) : stream->nmsgs;
++ stream->nmsgs = maildir_parse_dir(stream, total, New, namesnew,
++ nfilesnew, full);
++ }
++ if(namesnew){
++ for(i = 0L; i < nfilesnew; i++)
++ fs_give((void **)&namesnew[i]);
++ fs_give((void **) &namesnew);
++ }
++ if(namescur){
++ for(i = 0L; i < nfilescur; i++)
++ fs_give((void **)&namescur[i]);
++ fs_give((void **) &namescur);
++ }
++ MM_NOCRITICAL(stream);
++ }
++
++ int
++ maildir_initial_check (MAILSTREAM *stream, DirNamesType dirtype)
++ {
++ char tmp[MAILTMPLEN];
++ struct stat sbuf;
++
++ MDFLD(tmp, LOCAL->dir, dirtype);
++ if (access (tmp, R_OK|W_OK|X_OK) != 0){
++ maildir_abort(stream);
++ return -1;
++ }
++
++ MDFLD(tmp, LOCAL->dir, Cur);
++ if (dirtype != New &&
++ (stat(tmp, &sbuf) < 0 || sbuf.st_ctime == LOCAL->scantime))
++ return -1;
++ return 0;
++ }
++
++
++ /* Return the number of messages in the directory, while filling the
++ * elt structure.
++ */
++
++ unsigned long
++ maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs,
++ DirNamesType dirtype, struct direct **names,
++ unsigned long nfiles, int full)
++ {
++ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], file[MAILTMPLEN],
++ newfile[MAILTMPLEN], *mdstr;
++ struct stat sbuf;
++ unsigned long i, new = 0L, l, uid_last;
++ unsigned long recent = stream ? stream->recent : 0L;
++ int d = 0, f = 0, r = 0, s = 0, t = 0;
++ int we_compute, in_list;
++ int silent = stream ? stream->silent : NIL;
++ MESSAGECACHE *elt;
++
++ MDFLD(tmp, LOCAL->dir, dirtype);
++ if (dirtype == Cur && !stream->rdonly)
++ for (i = 1L; i <= stream->nmsgs;){
++ elt = mail_elt(stream, i);
++ in_list = elt && elt->private.spare.ptr && nfiles > 0L
++ ? (MDPOS(elt) < nfiles
++ ? same_maildir_file(MDFILE(elt), names[MDPOS(elt)]->d_name)
++ : NIL)
++ || maildir_message_in_list(MDFILE(elt), names, 0L,
++ nfiles - 1L, &MDPOS(elt))
++ : NIL;
++ if (!in_list){
++ if (elt->private.spare.ptr)
++ maildir_free_file ((void **) &elt->private.spare.ptr);
++
++ if (elt->recent) --recent;
++ mail_expunged(stream,i);
++ }
++ else i++;
++ }
++
++ stream->silent = T;
++ uid_last = 0L;
++ for (we_compute = 0, i = l = 1L; l <= nfiles; l++){
++ unsigned long pos, uid;
++ if (dirtype == New && !stream->rdonly){ /* move new messages to cur */
++ pos = l - 1L;
++ sprintf (file,"%s/%s", tmp, names[pos]->d_name);
++ if(lstat(file,&sbuf) == 0)
++ switch(sbuf.st_mode & S_IFMT){
++ case S_IFREG:
++ strcpy(tmp2, names[pos]->d_name);
++ if((mdstr = strstr(tmp2,MDSEP(3)))
++ || (mdstr = strstr(tmp2,MDSEP(2))))
++ *(mdstr+1) = '2';
++ else
++ strcat(tmp2, MDSEP(2));
++ sprintf(newfile, "%s/%s",LOCAL->curdir, tmp2);
++ if(rename (file, newfile) != 0){
++ mm_log("Unable to read new mail!", WARN);
++ continue;
++ }
++ unlink (file);
++ new++;
++ break;
++ case S_IFLNK: /* clean up, clean up, everybody, everywhere */
++ if(unlink(file) < 0){
++ if(LOCAL->link == NIL){
++ mm_log("Unable to remove symbolic link", WARN);
++ LOCAL->link = T;
++ }
++ }
++ continue;
++ break;
++ default:
++ if(LOCAL && LOCAL->link == NIL){
++ mm_log("Unrecognized file or link in folder", WARN);
++ LOCAL->link = T;
++ }
++ continue;
++ break;
++ }
++ }
++ mail_exists(stream, i + nmsgs);
++ elt = mail_elt(stream, i + nmsgs);
++ pos = (elt && elt->private.spare.ptr) ? MDPOS(elt) : l - 1L;
++ if (dirtype == New) elt->recent = T;
++ maildir_getflag(names[pos]->d_name, &d, &f, &r ,&s, &t);
++ if (elt->private.spare.ptr)
++ maildir_free_file_only ((void **)&elt->private.spare.ptr);
++ else{
++ maildir_get_file((MAILDIRFILE **)&elt->private.spare.ptr);
++ we_compute++;
++ }
++ MDFILE(elt) = cpystr(names[pos]->d_name);
++ MDPOS(elt) = pos;
++ MDLOC(elt) = dirtype;
++ if (dirtype == Cur){ /* deal with UIDs */
++ if(elt->private.uid == 0L)
++ elt->private.uid = maildir_get_uid(MDFILE(elt));
++ if(elt->private.uid <= uid_last){
++ uid = (we_compute ? uid_last : stream->uid_last) + 1L;
++ if(LOCAL->candouid)
++ maildir_assign_uid(stream, i + nmsgs, uid);
++ else
++ elt->private.uid = uid;
++ }
++ else
++ uid = elt->private.uid;
++ uid_last = uid;
++ if(uid_last > stream->uid_last)
++ stream->uid_last = uid_last;
++ }
++ if(dirtype == New && !stream->rdonly){
++ maildir_free_file_only((void **)&elt->private.spare.ptr);
++ MDFILE(elt) = cpystr(tmp2);
++ MDSIZE(elt) = sbuf.st_size;
++ MDMTIME(elt) = sbuf.st_mtime;
++ MDLOC(elt) = Cur;
++ }
++ if (elt->draft != d || elt->flagged != f ||
++ elt->answered != r || elt->seen != s || elt->deleted != t){
++ elt->draft = d; elt->flagged = f; elt->answered = r;
++ elt->seen = s; elt->deleted = t;
++ if (!we_compute && !stream->rdonly)
++ MM_FLAGS(stream, i+nmsgs);
++ }
++ maildir_get_date(stream, i+nmsgs);
++ elt->valid = T;
++ i++;
++ }
++ stream->silent = silent;
++ if(LOCAL->candouid && dirtype == Cur)
++ maildir_read_uid(stream, NULL, &stream->uid_validity);
++ if (dirtype == New && stream->rdonly)
++ new = nfiles;
++ mail_exists(stream, nmsgs + ((dirtype == New) ? new : nfiles));
++ mail_recent(stream, recent + ((dirtype == New) ? new : 0L));
++
++ return (nmsgs + (dirtype == New ? new : nfiles));
++ }
++
++ long maildir_ping (MAILSTREAM *stream)
++ {
++ maildir_parse_folder(stream, 0);
++ if(stream && LOCAL){
++ if(LOCAL->candouid)
++ maildir_uid_renew_tempfile(stream);
++ else /* try again to get uids */
++ LOCAL->candouid = maildir_can_assign_uid(stream);
++ }
++ return stream && LOCAL ? LONGT : NIL;
++ }
++
++ int maildir_select (const struct direct *name)
++ {
++ return (name->d_name[0] != '.');
++ }
++
++ /*
++ * Unfortunately, there is no way to sort by arrival in this driver, this
++ * means that opening a folder in this driver using the scandir function
++ * will always make this driver slower than any driver that has a natural
++ * way of sorting by arrival (like a flat file format, "mbox", "mbx", etc).
++ */
++ int maildir_namesort (const void *d1, const void *d2)
++ {
++ const struct direct *e1 = *(const struct direct **) d1;
++ const struct direct *e2 = *(const struct direct **) d2;
++
++ return comp_maildir_file((char *) e1->d_name, (char *) e2->d_name);
++ }
++
++ /* Maildir close */
++
++ void maildir_close (MAILSTREAM *stream, long options)
++ {
++ MESSAGECACHE *elt;
++ unsigned long i;
++ int silent = stream ? stream->silent : 0;
++ mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL);
++
++ if (!stream) return;
++
++ for (i = 1L; i <= stream->nmsgs; i++)
++ if((elt = (MESSAGECACHE *) (*mc)(stream,i,CH_ELT)) && elt->private.spare.ptr)
++ maildir_free_file ((void **) &elt->private.spare.ptr);
++ stream->silent = T;
++ if (options & CL_EXPUNGE) maildir_expunge (stream, NIL, NIL);
++ maildir_abort(stream);
++ if (mdfpath) fs_give((void **)&mdfpath);
++ if (mypid) mypid = (pid_t) 0;
++ stream->silent = silent;
++ }
++
++ void maildir_check (MAILSTREAM *stream)
++ {
++ if (maildir_ping (stream)) mm_log ("Check completed",(long) NIL);
++ }
++
++ long maildir_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs, long flags)
++ {
++ char tmp[MAILTMPLEN];
++ unsigned long i;
++ MESSAGECACHE *elt;
++ char *s;
++ /* UID call "impossible" */
++ if (flags & FT_UID || !LOCAL) return NIL;
++ elt = mail_elt (stream, msgno);
++
++ if (!(flags & FT_PEEK) && !elt->seen){
++ elt->seen = T;
++ maildir_flagmsg (stream, elt);
++ MM_FLAGS(stream, elt->msgno);
++ }
++
++ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(elt));
++ if (LOCAL->fd < 0) /* if file closed ? */
++ LOCAL->fd = open(tmp,O_RDONLY,NIL);
++
++ if (LOCAL->fd < 0 && (errno == EACCES || errno == ENOENT)){
++ INIT (bs, mail_string, "", 0);
++ elt->rfc822_size = 0L;
++ return NIL;
++ }
++
++ s = maildir_text_work(stream, elt, &i, flags);
++ INIT (bs, mail_string, s, i);
++ return LONGT;
++ }
++
++ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt,
++ unsigned long *length,long flags)
++ {
++ FDDATA d;
++ STRING bs;
++ char *s,tmp[CHUNK];
++ unsigned long msgno = elt->msgno;
++ static int try = 0;
++
++ if (length)
++ *length = 0L;
++ LOCAL->buf[0] = '\0';
++
++ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(elt));
++ if (LOCAL->fd < 0) /* if file closed ? */
++ LOCAL->fd = open(tmp,O_RDONLY,NIL);
++
++ if (LOCAL->fd < 0){ /* flag change? */
++ if (try < 5){
++ try++;
++ if (maildir_update_elt_maildirp(stream, msgno) > 0)
++ try = 0;
++ return maildir_text_work(stream, mail_elt(stream, msgno),length, flags);
++ }
++ try = 0;
++ return NULL;
++ }
++
++ lseek (LOCAL->fd, elt->private.msg.text.offset,L_SET);
++
++ if (flags & FT_INTERNAL) { /* initial data OK? */
++ if (elt->private.msg.text.text.size > LOCAL->buflen) {
++ fs_give ((void **) &LOCAL->buf);
++ LOCAL->buf = (char *) fs_get ((LOCAL->buflen =
++ elt->private.msg.text.text.size) + 1);
++ }
++ read (LOCAL->fd,LOCAL->buf,elt->private.msg.text.text.size);
++ LOCAL->buf[*length = elt->private.msg.text.text.size] = '\0';
++ }
++ else {
++ if (elt->rfc822_size > LOCAL->buflen) {
++ fs_give ((void **) &LOCAL->buf);
++ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = elt->rfc822_size) + 1);
++ }
++ d.fd = LOCAL->fd; /* yes, set up file descriptor */
++ d.pos = elt->private.msg.text.offset;
++ d.chunk = tmp; /* initial buffer chunk */
++ d.chunksize = CHUNK;
++ INIT (&bs,fd_string,&d,elt->private.msg.text.text.size);
++ for (s = LOCAL->buf; SIZE (&bs);) switch (CHR (&bs)) {
++ case '\r': /* carriage return seen */
++ *s++ = SNX (&bs); /* copy it and any succeeding LF */
++ if (SIZE (&bs) && (CHR (&bs) == '\n')) *s++ = SNX (&bs);
++ break;
++ case '\n':
++ *s++ = '\r'; /* insert a CR */
++ default:
++ *s++ = SNX (&bs); /* copy characters */
++ }
++ *s = '\0'; /* tie off buffer */
++ *length = s - (char *) LOCAL->buf; /* calculate length */
++ }
++ close(LOCAL->fd); LOCAL->fd = -1;
++ return LOCAL->buf;
++ }
++
++ /* maildir parse, fill the elt structure... well not all of it... */
++ unsigned long maildir_parse_message(MAILSTREAM *stream, unsigned long msgno,
++ DirNamesType dirtype)
++ {
++ char *b, *s, *t, c;
++ char tmp[MAILTMPLEN];
++ struct stat sbuf;
++ unsigned long i, len;
++ int d, f, r, se, dt;
++ MESSAGECACHE *elt;
++
++ elt = mail_elt (stream,msgno);
++ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), dirtype);
++ if(stat(tmp, &sbuf) == 0)
++ MDSIZE(elt) = sbuf.st_size;
++
++ maildir_get_date(stream, msgno);
++ maildir_getflag(MDFILE(elt), &d, &f, &r ,&se, &dt);
++ elt->draft = d; elt->flagged = f; elt->answered = r; elt->seen = se;
++ elt->deleted = dt; elt->valid = T;
++ if (LOCAL->fd < 0) /* if file closed ? */
++ LOCAL->fd = open(tmp,O_RDONLY,NIL);
++
++ if (LOCAL->fd >= 0){
++ s = (char *) fs_get (MDSIZE(elt) + 1);
++ read (LOCAL->fd,s,MDSIZE(elt));
++ s[MDSIZE(elt)] = '\0';
++ t = s + strlen(s); /* make t point to the end of s */
++ for (i = 0L, b = s; b < t && !(i && (*b == '\n')); i = (*b++ == '\n'));
++ len = (*b ? ++b : b) - s;
++ elt->private.msg.header.text.size =
++ elt->private.msg.text.offset = len;
++ elt->private.msg.text.text.size = MDSIZE(elt) - len;
++ for (i = 0L, b = s, c = *b; b &&
++ ((c < '\016' && ((c == '\012' && ++i)
++ ||(c == '\015' && *(b+1) == '\012' && ++b && (i +=2))))
++ || b < t); i++, c= *++b);
++ elt->rfc822_size = i;
++ fs_give ((void **) &s);
++ close(LOCAL->fd); LOCAL->fd = -1;
++ }
++ return elt->rfc822_size;
++ }
++
++ int
++ maildir_update_elt_maildirp(MAILSTREAM *stream, unsigned long msgno)
++ {
++ char tmp[MAILTMPLEN];
++ struct direct **names = NIL;
++ unsigned long i, nfiles, pos;
++ int d = 0, f = 0 , r = 0, s = 0, t = 0, in_list, scan_err;
++ MESSAGECACHE *elt;
++
++ MDFLD(tmp, LOCAL->dir, Cur);
++
++ maildir_scandir (tmp, &names, &nfiles, &scan_err, CCLIENT);
++
++ elt = mail_elt (stream,msgno);
++
++ in_list = nfiles > 0L
++ ? maildir_message_in_list(MDFILE(elt), names, 0L, nfiles - 1L, &pos)
++ : NIL;
++
++ if (in_list && pos >= 0L && pos < nfiles
++ && !strcmp(MDFILE(elt), names[pos]->d_name)){
++ in_list = NIL;
++ maildir_abort(stream);
++ }
++
++ if (in_list && pos >= 0L && pos < nfiles){
++ maildir_free_file_only((void **)&elt->private.spare.ptr);
++ MDFILE(elt) = cpystr(names[pos]->d_name);
++ maildir_getflag(MDFILE(elt), &d, &f, &r ,&s, &t);
++ if (elt->draft != d || elt->flagged != f ||
++ elt->answered != r || elt->seen != s || elt->deleted != t){
++ elt->draft = d; elt->flagged = f; elt->answered = r;
++ elt->seen = s; elt->deleted = t;
++ MM_FLAGS(stream, msgno);
++ }
++ }
++ for (i = 0L; i < nfiles; i++)
++ fs_give((void **) &names[i]);
++ if (names)
++ fs_give((void **) &names);
++ return in_list ? 1 : -1;
++ }
++
++ /* Maildir fetch message header */
++
++ char *maildir_header (MAILSTREAM *stream,unsigned long msgno,
++ unsigned long *length, long flags)
++ {
++ char tmp[MAILTMPLEN], *s;
++ MESSAGECACHE *elt;
++ static int try = 0;
++
++ if (length) *length = 0;
++ if (flags & FT_UID || !LOCAL) return ""; /* UID call "impossible" */
++ elt = mail_elt (stream,msgno);
++ if(elt->private.msg.header.text.size == 0)
++ maildir_parse_message(stream, msgno, MDLOC(elt));
++
++ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(elt));
++ if (LOCAL->fd < 0)
++ LOCAL->fd = open (tmp,O_RDONLY,NIL);
++
++ if (LOCAL->fd < 0 && errno == EACCES){
++ mm_log ("Message exists but can not be read. Envelope and body lost!",ERROR);
++ return NULL;
++ }
++
++ if (LOCAL->fd < 0){ /* flag change? */
++ if (try < 5){
++ try++;
++ if (maildir_update_elt_maildirp(stream, msgno) > 0)
++ try = 0;
++ return maildir_header(stream, msgno, length, flags);
++ }
++ try = 0;
++ return NULL;
++ }
++
++ if (flags & FT_INTERNAL){
++ if(elt->private.msg.header.text.size > LOCAL->buflen){
++ fs_give ((void **) &LOCAL->buf);
++ LOCAL->buf = (char *) fs_get ((LOCAL->buflen =
++ elt->private.msg.header.text.size) + 1);
++ }
++ read (LOCAL->fd, (void *)LOCAL->buf, elt->private.msg.header.text.size);
++ LOCAL->buf[*length = elt->private.msg.header.text.size] = '\0';
++ }
++ else{
++ s = (char *) fs_get(elt->private.msg.header.text.size+1);
++ read (LOCAL->fd, (void *)s, elt->private.msg.header.text.size);
++ s[elt->private.msg.header.text.size] = '\0';
++ *length = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen,s,
++ elt->private.msg.header.text.size);
++ fs_give ((void **) &s);
++ }
++ elt->private.msg.text.offset = elt->private.msg.header.text.size;
++ elt->private.msg.text.text.size = MDSIZE(elt) - elt->private.msg.text.offset;
++ close(LOCAL->fd); LOCAL->fd = -1;
++ return LOCAL->buf;
++ }
++
++ /* Maildir find list of subscribed mailboxes
++ * Accepts: mail stream
++ * pattern to search
++ */
++
++ void maildir_list (MAILSTREAM *stream,char *ref, char *pat)
++ {
++ char *s,test[MAILTMPLEN],file[MAILTMPLEN];
++ long i = 0L;
++
++ if((!pat || !*pat) && maildir_canonicalize (test,ref,"*")
++ && maildir_valid_name(test)){ /* there is a #md/ leading here */
++ for (i = 3L; test[i] && test[i] != '/'; i++);
++ if ((s = strchr (test+i+1,'/')) != NULL) *++s = '\0';
++ else test[0] = '\0';
++ mm_list (stream,'/',test, LATT_NOSELECT);
++ }
++ else if (maildir_canonicalize (test,ref,pat)) {
++ if (test[3] == '/') { /* looking down levels? */
++ /* yes, found any wildcards? */
++ if ((s = strpbrk (test,"%*")) != NULL){
++ /* yes, copy name up to that point */
++ strncpy (file,test+4,i = s - (test+4));
++ file[i] = '\0'; /* tie off */
++ }
++ else strcpy (file,test+4);/* use just that name then */
++ /* find directory name */
++ if ((s = strrchr (file, '/')) != NULL){
++ *s = '\0'; /* found, tie off at that point */
++ s = file;
++ }
++ /* do the work */
++ if(IS_COURIER(test))
++ courier_list_work (stream,s,test,0);
++ else
++ maildir_list_work (stream,s,test,0);
++ }
++ /* always an INBOX */
++ if (!compare_cstring (test,"#MD/INBOX"))
++ mm_list (stream,NIL,"#MD/INBOX",LATT_NOINFERIORS);
++ if (!compare_cstring (test,"#MC/INBOX"))
++ mm_list (stream,NIL,"#MC/INBOX",LATT_NOINFERIORS);
++ }
++ }
++
++ void courier_list (MAILSTREAM *stream,char *ref, char *pat)
++ {
++ /* I am too lazy to do anything. Do you care to ask maildir list, please?
++ The real reason why this is a dummy function is because we do not want to
++ see the same folder listed twice.
++ */
++ }
++
++ /* For those that want to hide things, we give them a chance to do so */
++ void *maildir_parameters (long function, void *value)
++ {
++ void *ret = NIL;
++ switch ((int) function) {
++ case SET_MDINBOXPATH:
++ if(strlen((char *) value ) > 49)
++ strcpy(myMdInboxDir, "Maildir");
++ else
++ strcpy(myMdInboxDir, (char *) value);
++ case GET_MDINBOXPATH:
++ if (myMdInboxDir[0] == '\0') strcpy(myMdInboxDir,"Maildir");
++ ret = (void *) myMdInboxDir;
++ break;
++ case SET_COURIERSTYLE:
++ CourierStyle = (long) value;
++ case GET_COURIERSTYLE:
++ ret = (void *) CourierStyle;
++ break;
++ case GET_DIRFMTTEST:
++ ret = (void *) maildir_dirfmttest;
++ break;
++ default:
++ break;
++ }
++ return ret;
++ }
++
++ int maildir_create_folder(char *mailbox)
++ {
++ char tmp[MAILTMPLEN], err[MAILTMPLEN];
++ int i;
++
++ for (i = Cur; i != EndDir; i++){
++ MDFLD(tmp, mailbox, i);
++ if (mkdir(tmp, 0700) && errno != EEXIST){ /* try to make new dir */
++ sprintf (err, "Can't create %s: %s", tmp, strerror(errno));
++ mm_log (err,ERROR);
++ return NIL;
++ }
++ }
++ return T;
++ }
++
++ int maildir_create_work(char *mailbox, int loop)
++ {
++ char *s, c, err[MAILTMPLEN], tmp[MAILTMPLEN], tmp2[MAILTMPLEN], mbx[MAILTMPLEN];
++ int fnlen, create_dir = 0, courier, mv;
++ struct stat sbuf;
++ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL);
++
++ courier = IS_COURIER(mailbox);
++ strcpy(mbx, mailbox);
++ mv = maildir_valid(mbx) ? 1 : 0;
++ maildir_file_path(mailbox, tmp);
++ if (mailbox[strlen(mailbox) - 1] == MDSEPARATOR(courier)){
++ create_dir++;
++ mailbox[strlen(mailbox) - 1] = '\0';
++ }
++
++ if(!loop && courier){
++ if(mv){
++ if(create_dir){
++ if(style == CCLIENT)
++ strcpy (err,"Can not create directory: folder exists. Create subfolder");
++ else
++ strcpy(err,"Folder and Directory already exist");
++ }
++ else
++ strcpy (err, "Can't create mailbox: mailbox already exists");
++ }
++ else{
++ if(create_dir)
++ strcpy(err, "Can not create directory. Cread folder instead");
++ else
++ err[0] = '\0';
++ }
++ if(err[0]){
++ mm_log (err,ERROR);
++ return NIL;
++ }
++ }
++
++ fnlen = strlen(tmp);
++ if ((s = strrchr(mailbox,MDSEPARATOR(courier))) != NULL){
++ c = *++s;
++ *s = '\0';
++ if ((stat(tmp,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) &&
++ !maildir_create_work (mailbox, ++loop))
++ return NIL;
++ *s = c;
++ }
++ tmp[fnlen] = '\0';
++
++ if (mkdir(tmp,0700) && errno != EEXIST)
++ return NIL;
++
++ if (create_dir)
++ mailbox[fnlen] = '/';
++
++ if (create_dir){
++ if(style == CCLIENT){
++ if(!courier){
++ FILE *fp = NULL;
++ sprintf(tmp2,"%s%s", tmp, MDDIR);
++ if ((fp = fopen(tmp2,"w")) == NULL){
++ sprintf (err,"Problem creating %s: %s", tmp2, strerror(errno));
++ mm_log (err,ERROR);
++ return NIL;
++ }
++ fclose(fp);
++ }
++ }
++ return T;
++ }
++ else
++ return maildir_create_folder(tmp);
++ }
++
++ long maildir_create (MAILSTREAM *stream,char *mailbox)
++ {
++ char tmp[MAILTMPLEN], err[MAILTMPLEN];
++ int rv, create_dir;
++
++ create_dir = mailbox ?
++ (mailbox[strlen(mailbox) - 1] ==
++ MDSEPARATOR(IS_COURIER(mailbox))) : 0;
++ maildir_file_path(mailbox, tmp);
++ strcpy(tmp, mailbox);
++ rv = maildir_create_work(mailbox, 0);
++ strcpy(mailbox, tmp);
++ if (rv == 0){
++ sprintf (err,"Can't create %s %s",
++ (create_dir ? "directory" : "mailbox"), mailbox);
++ mm_log (err,ERROR);
++ }
++ return rv ? LONGT : NIL;
++ }
++
++ #define MAXTRY 10000
++ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt)
++ {
++ char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN];
++ char *s;
++ int ren, try = 0;
++
++ if (elt->valid){
++ for (try = 1; try > 0 && try < MAXTRY; try++){
++ /* build the new filename */
++ sprintf (oldfile,"%s/%s",LOCAL->curdir, MDFILE(elt));
++ fn[0] = '\0';
++ if ((ren = maildir_message_exists(stream, MDFILE(elt), fn)) == 0){
++ errno = ENOENT;
++ try = MAXTRY;
++ }
++ if (*fn) /* new oldfile! */
++ sprintf (oldfile,"%s/%s",LOCAL->curdir,fn);
++ if ((s = strrchr (MDFILE(elt), FLAGSEP))) *s = '\0';
++ sprintf (fn,"%s%s%s%s%s%s%s", MDFILE(elt), MDSEP(2),
++ MDFLAG(Draft, elt->draft), MDFLAG(Flagged, elt->flagged),
++ MDFLAG(Replied, elt->answered), MDFLAG(Seen, elt->seen),
++ MDFLAG(Trashed, elt->deleted));
++ sprintf (newfile,"%s/%s",LOCAL->curdir,fn);
++ if (ren != 0 && rename (oldfile,newfile) >= 0)
++ try = -1;
++ }
++
++ if (try > 0){
++ sprintf(oldfile,"Unable to write flags to disk: %s",
++ (errno == ENOENT) ? "message is gone!" : strerror (errno));
++ mm_log(oldfile,ERROR);
++ return;
++ }
++ #ifdef __CYGWIN__
++ utime(LOCAL->curdir, NIL); /* make sure next scan will catch the change */
++ #endif
++ maildir_free_file_only ((void **) &elt->private.spare.ptr);
++ MDFILE(elt) = cpystr (fn);
++ }
++ }
++
++ long maildir_expunge (MAILSTREAM *stream, char *sequence, long options)
++ {
++ long ret;
++ MESSAGECACHE *elt;
++ unsigned long i, n = 0L;
++ unsigned long recent = stream->recent;
++ char tmp[MAILTMPLEN];
++
++ mm_critical (stream); /* go critical */
++ ret = sequence ? ((options & EX_UID) ?
++ mail_uid_sequence (stream,sequence) :
++ mail_sequence (stream,sequence)) : LONGT;
++ if(ret == 0L)
++ return 0L;
++ for (i = 1L; i <= stream->nmsgs;){
++ elt = mail_elt (stream,i);
++ if (elt->deleted && (sequence ? elt->sequence : T)){
++ sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt));
++ if (unlink (tmp) < 0) {/* try to delete the message */
++ sprintf (tmp,"Expunge of message %ld failed, aborted: %s",i,
++ strerror (errno));
++ if (!stream->silent)
++ mm_log (tmp,WARN);
++ break;
++ }
++ if (elt->private.spare.ptr)
++ maildir_free_file ((void **) &elt->private.spare.ptr);
++ if (elt->recent) --recent;/* if recent, note one less recent message */
++ mail_expunged (stream,i); /* notify upper levels */
++ n++; /* count up one more expunged message */
++ }
++ else i++;
++ }
++ if(n){ /* output the news if any expunged */
++ sprintf (tmp,"Expunged %ld messages",n);
++ if (!stream->silent)
++ mm_log (tmp,(long) NIL);
++ }
++ else
++ if (!stream->silent)
++ mm_log ("No messages deleted, so no update needed",(long) NIL);
++ mm_nocritical (stream); /* release critical */
++ /* notify upper level of new mailbox size */
++ mail_exists (stream,stream->nmsgs);
++ mail_recent (stream,recent);
++ return ret;
++ }
++
++ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options)
++ {
++ STRING st;
++ MESSAGECACHE *elt;
++ unsigned long len;
++ int fd;
++ unsigned long i;
++ struct stat sbuf;
++ char tmp[MAILTMPLEN], flags[MAILTMPLEN], path[MAILTMPLEN], *s;
++ /* copy the messages */
++ if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) :
++ mail_sequence (stream,sequence))
++ for (i = 1L; i <= stream->nmsgs; i++)
++ if ((elt = mail_elt (stream,i))->sequence){
++ MSGPATH(path, LOCAL->dir, MDFILE(elt), MDLOC(elt));
++ if (((fd = open (path,O_RDONLY,NIL)) < 0)
++ ||((!elt->rfc822_size &&
++ ((stat(path, &sbuf) < 0) || !S_ISREG (sbuf.st_mode)))))
++ return NIL;
++ if(!elt->rfc822_size)
++ MDSIZE(elt) = sbuf.st_size;
++ s = (char *) fs_get(MDSIZE(elt) + 1);
++ read (fd,s,MDSIZE(elt));
++ s[MDSIZE(elt)] = '\0';
++ close (fd);
++ len = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen, s, MDSIZE(elt));
++ INIT (&st,mail_string, LOCAL->buf, len);
++ elt->rfc822_size = len;
++ fs_give ((void **)&s);
++
++ flags[0] = flags[1] = '\0';
++ if (elt->seen) strcat (flags," \\Seen");
++ if (elt->draft) strcat (flags," \\Draft");
++ if (elt->deleted) strcat (flags," \\Deleted");
++ if (elt->flagged) strcat (flags," \\Flagged");
++ if (elt->answered) strcat (flags," \\Answered");
++ flags[0] = '('; /* open list */
++ strcat (flags,")"); /* close list */
++ mail_date (tmp,elt); /* generate internal date */
++ if (!mail_append_full (NIL,mailbox,flags,tmp,&st))
++ return NIL;
++ if (options & CP_MOVE) elt->deleted = T;
++ }
++ return LONGT; /* return success */
++ }
++
++ long maildir_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
++ {
++ int fd, k;
++ STRING *message;
++ char c,*s, *flags, *date;
++ char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN];
++ MESSAGECACHE elt;
++ long i, size = 0L, ret = LONGT, f;
++ unsigned long uf, ti;
++ static unsigned int transact = 0;
++
++ if (!maildir_valid(mailbox)) {
++ sprintf (tmp,"Not a valid Maildir mailbox: %s",mailbox);
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++
++ if (!*mdlocaldomain)
++ md_domain_name(); /* get domain name for maildir files in mdlocaldomain now! */
++
++ if (mypid == (pid_t) 0)
++ mypid = getpid();
++
++ if (!stream){
++ stream = &maildirproto;
++
++ for (k = 0; k < NUSERFLAGS && stream->user_flags[k]; ++k)
++ fs_give ((void **) &stream->user_flags[k]);
++ }
++
++ if (!(*af) (stream,data,&flags,&date,&message)) return NIL;
++
++ mm_critical (stream); /* go critical */
++ /* call time(0) only once, use transact to distinguish instead */
++ ti = time(0);
++ do {
++ if (!SIZE (message)) { /* guard against zero-length */
++ mm_log ("Append of zero-length message",ERROR);
++ ret = NIL;
++ break;
++ }
++ if (date && !mail_parse_date(&elt,date)){
++ sprintf (tmp,"Bad date in append: %.80s",date);
++ mm_log (tmp,ERROR);
++ ret = NIL;
++ break;
++ }
++ f = mail_parse_flags (stream,flags,&uf);
++ /* build file name we will use */
++ sprintf (file,"%lu.%d_%09u.%s%s%s%s%s%s",
++ ti, mypid, transact++, mdlocaldomain, (f ? MDSEP(2) : ""),
++ MDFLAG(Draft, f&fDRAFT), MDFLAG(Flagged, f&fFLAGGED),
++ MDFLAG(Replied, f&fANSWERED), MDFLAG(Seen, f&fSEEN));
++ /* build tmp file name */
++ if (maildir_file_path(mailbox, tmp))
++ MSGPATH(path1, tmp, file, Tmp);
++
++ if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {
++ sprintf (tmp, "Can't open append mailbox: %s", strerror (errno));
++ mm_log (tmp, ERROR);
++ return NIL;
++ }
++ for (size = 0,i = SIZE (message),s = (char *) fs_get (i + 1); i; --i)
++ if ((c = SNX (message)) != '\015') s[size++] = c;
++ if ((write (fd, s, size) < 0) || fsync (fd)) {
++ unlink (path1); /* delete message */
++ sprintf (tmp, "Message append failed: %s", strerror (errno));
++ mm_log (tmp, ERROR);
++ ret = NIL;
++ }
++ fs_give ((void **) &s); /* flush the buffer */
++ close (fd); /* close the file */
++ /* build final filename to use */
++ if (maildir_file_path(mailbox, tmp))
++ MSGPATH(path2, tmp, file, New);
++ if (rename (path1,path2) < 0) {
++ sprintf (tmp, "Message append failed: %s", strerror (errno));
++ mm_log (tmp, ERROR);
++ ret = NIL;
++ }
++ unlink (path1);
++
++ if (ret)
++ if (!(*af) (stream,data,&flags,&date,&message)) ret = NIL;
++
++ } while (ret && message); /* write the data */
++ mm_nocritical (stream); /* release critical */
++ return ret;
++ }
++
++ long maildir_delete (MAILSTREAM *stream,char *mailbox)
++ {
++ DIR *dirp;
++ struct direct *d;
++ int i, remove_dir = 0, mddir = 0, rv, error = 0;
++ char tmp[MAILTMPLEN],tmp2[MAILTMPLEN], realname[MAILTMPLEN];
++ struct stat sbuf;
++ int courier = IS_COURIER(mailbox);
++
++ if (mailbox[strlen(mailbox) - 1] == MDSEPARATOR(courier)){
++ remove_dir++;
++ mailbox[strlen(mailbox) -1] = '\0';
++ }
++
++ if (!maildir_valid(mailbox)){
++ maildir_file_path(mailbox, tmp);
++ if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode)){
++ sprintf(tmp,"Can not remove %s", mailbox);
++ error++;
++ }
++ }
++
++ if (!error && remove_dir && !maildir_dir_is_empty(mailbox)){
++ sprintf(tmp,"Can not remove directory %s/: directory not empty", mailbox);
++ error++;
++ }
++
++ if(error){
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++
++ maildir_close(stream,0); /* even if stream was NULL */
++
++ maildir_file_path(mailbox, realname);
++
++ if (remove_dir){
++ sprintf(tmp,"%s/%s", realname, MDDIR);
++ if ((rv = stat (tmp,&sbuf)) == 0 && S_ISREG(sbuf.st_mode))
++ rv = unlink(tmp);
++ else if (errno == ENOENT)
++ rv = 0;
++ if (rv != 0){
++ sprintf(tmp,"Can not remove %s/%s: %s", tmp2, MDDIR, strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ if (!maildir_valid(realname) && rmdir(realname) != 0){
++ sprintf(tmp,"Can not remove %s/: %s", mailbox, strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ return LONGT;
++ }
++ /* else remove just the folder. Remove all hidden files, except MDDIR */
++ for (i = Cur; i != EndDir; i++){
++ MDFLD(tmp, realname, i);
++
++ if (!(dirp = opendir (tmp))){
++ sprintf(tmp,"Can not read %s/: %s", mailbox, strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++
++ while ((d = readdir(dirp)) != NULL){
++ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")){
++ sprintf(tmp2,"%s/%s", tmp, d->d_name);
++ if (unlink(tmp2) != 0){
++ sprintf(tmp2,"Can not remove %s: %s", mailbox, strerror(errno));
++ mm_log (tmp2,ERROR);
++ return NIL;
++ }
++ }
++ }
++ closedir(dirp);
++ if (rmdir(tmp) != 0){
++ sprintf(tmp,"Can not remove %s: %s", mailbox, strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ }
++ /*
++ * ok we have removed all subdirectories of the folder mailbox, Remove the
++ * hidden files.
++ */
++
++ if(!(dirp = opendir (realname))){
++ sprintf(tmp,"Can not read %s/: %s", realname, strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++
++ while ((d = readdir(dirp)) != NULL){
++ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
++ && (!strcmp(d->d_name, MDDIR)
++ || !strncmp(d->d_name, MDUIDLAST, strlen(MDUIDLAST))
++ || !strncmp(d->d_name, MDUIDTEMP, strlen(MDUIDTEMP)))){
++ if(strcmp(d->d_name, MDDIR) == 0)
++ mddir++;
++ sprintf(tmp,"%s/%s", realname, d->d_name);
++ if (unlink(tmp) != 0)
++ error++;
++ }
++ }
++ closedir(dirp);
++ if (error ||
++ (maildir_dir_is_empty(mailbox) && mddir == 0 && rmdir(realname) < 0)){
++ sprintf(tmp,"Can not remove folder %s: %s", mailbox, strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ return LONGT;
++ }
++
++ long maildir_rename (MAILSTREAM *stream, char *old, char *new)
++ {
++ char tmp[MAILTMPLEN],tmpnew[MAILTMPLEN], realold[MAILTMPLEN];
++ char realnew[MAILTMPLEN];
++ int courier = IS_COURIER(old) && IS_COURIER(new);
++ int i;
++ long rv = LONGT;
++ COURIER_S *cdir;
++
++ if((IS_COURIER(old) || IS_COURIER(new)) && !courier){
++ sprintf (tmp,"Can't rename mailbox %s to %s",old, new);
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++
++ if (!maildir_valid(old)){
++ sprintf (tmp,"Can't rename mailbox %s: folder not in maildir format",old);
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ maildir_file_path(old, realold);
++ if (!maildir_valid_name(new) && new[0] == '#'){
++ sprintf (tmp,"Can't rename mailbox %s: folder not in maildir format",new);
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ maildir_file_path(new, realnew);
++ if (access(tmpnew,F_OK) == 0){ /* new mailbox name must not exist */
++ sprintf (tmp,"Can't rename to mailbox %s: destination already exists",new);
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++
++ if(!courier){
++ if (rename (realold,realnew)){ /* try to rename the directory */
++ sprintf (tmp,"Can't rename mailbox %s to %s: %s",old, new,
++ strerror(errno));
++ mm_log (tmp,ERROR);
++ return NIL;
++ }
++ return LONGT; /* return success */
++ }
++
++ cdir = courier_list_dir(old);
++ for (i = 0; cdir && i < cdir->total; i++){
++ if(strstr(cdir->data[i]->name, old)){
++ sprintf(tmp,"%s%s", new, cdir->data[i]->name+strlen(old));
++ maildir_file_path(cdir->data[i]->name, realold);
++ maildir_file_path(tmp, realnew);
++ if (rename (realold,realnew)){
++ sprintf (tmp,"Can't rename mailbox %s to %s: %s",old, new,
++ strerror(errno));
++ mm_log (tmp,ERROR);
++ rv = NIL;
++ }
++ }
++ }
++ courier_free_cdir(&cdir);
++ return rv;
++ }
++
++ long maildir_sub (MAILSTREAM *stream,char *mailbox)
++ {
++ return sm_subscribe (mailbox);
++ }
++
++ long maildir_unsub (MAILSTREAM *stream,char *mailbox)
++ {
++ return sm_unsubscribe (mailbox);
++ }
++
++ void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat)
++ {
++ void *sdb = NIL;
++ char *s, test[MAILTMPLEN];
++ /* get canonical form of name */
++ if (maildir_canonicalize (test,ref,pat) && (s = sm_read (&sdb))) {
++ do if (pmatch_full (s,test,'/')) mm_lsub (stream,'/',s,NIL);
++ while ((s = sm_read (&sdb)) != NULL); /* until no more subscriptions */
++ }
++ }
++
++ long maildir_canonicalize (char *pattern,char *ref,char *pat)
++ {
++ if (ref && *ref) { /* have a reference */
++ strcpy (pattern,ref); /* copy reference to pattern */
++ /* # overrides mailbox field in reference */
++ if (*pat == '#') strcpy (pattern,pat);
++ /* pattern starts, reference ends, with / */
++ else if ((*pat == '/') && (pattern[strlen (pattern) - 1] == '/'))
++ strcat (pattern,pat + 1); /* append, omitting one of the period */
++
++ else strcat (pattern,pat); /* anything else is just appended */
++ }
++ else strcpy (pattern,pat); /* just have basic name */
++ return maildir_valid_name(pattern) ? LONGT : NIL;
++ }
++
++ void maildir_list_work (MAILSTREAM *stream,char *dir,char *pat,long level)
++ {
++ DIR *dp;
++ struct direct *d;
++ struct stat sbuf;
++ char curdir[MAILTMPLEN],name[MAILTMPLEN], tmp[MAILTMPLEN];
++ char realpat[MAILTMPLEN];
++ long i;
++ char *maildirpath = mdirpath();
++
++ sprintf(curdir,"%s/%s/", myrootdir(pat), dir ? dir : maildirpath);
++ if ((dp = opendir (curdir)) != NULL){
++ if (dir) sprintf (name,"%s%s/",MDPREFIX(CCLIENT),dir);
++ else strcpy (name, pat);
++
++ if (level == 0 && !strpbrk(pat,"%*")){
++ if(maildir_valid(pat)){
++ i = maildir_contains_folder(pat, NULL)
++ ? LATT_HASCHILDREN
++ : (maildir_is_dir(pat, NULL)
++ ? LATT_HASNOCHILDREN : LATT_NOINFERIORS);
++ maildir_file_path(pat, realpat);
++ i += maildir_any_new_msgs(realpat)
++ ? LATT_MARKED : LATT_UNMARKED;
++ mm_list (stream,'/', pat, i);
++ }
++ else
++ if(pat[strlen(pat) - 1] == '/')
++ mm_list (stream,'/', pat, LATT_NOSELECT);
++ }
++
++ while ((d = readdir (dp)) != NULL)
++ if(strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
++ && strcmp(d->d_name, MDNAME(Cur))
++ && strcmp(d->d_name, MDNAME(Tmp))
++ && strcmp(d->d_name, MDNAME(New))){
++
++ if (dir) sprintf (tmp,"%s%s", name,d->d_name);
++ else strcpy(tmp, d->d_name);
++
++ if(pmatch_full (tmp, pat,'/')){
++ sprintf(tmp,"%s/%s/%s", myrootdir(d->d_name),
++ (dir ? dir : maildirpath), d->d_name);
++ if(stat (tmp,&sbuf) == 0
++ && ((sbuf.st_mode & S_IFMT) == S_IFDIR)){
++ if (dir) sprintf (tmp,"%s%s", name,d->d_name);
++ else strcpy(tmp, d->d_name);
++ i = maildir_valid(tmp)
++ ? (maildir_contains_folder(dir, d->d_name)
++ ? LATT_HASCHILDREN
++ : (maildir_is_dir(dir, d->d_name)
++ ? LATT_HASNOCHILDREN : LATT_NOINFERIORS))
++ : LATT_NOSELECT;
++ i += maildir_any_new_msgs(tmp)
++ ? LATT_MARKED : LATT_UNMARKED;
++ mm_list (stream,'/',tmp, i);
++ strcat (tmp, "/");
++ if(dmatch (tmp, pat,'/') &&
++ (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))){
++ sprintf(tmp,"%s/%s",dir,d->d_name);
++ maildir_list_work (stream,tmp,pat,level+1);
++ }
++ }
++ }
++ }
++ closedir (dp);
++ }
++ }
++
++ void courier_list_work (MAILSTREAM *stream, char *dir, char *pat, long level)
++ {
++ char c, curdir[MAILTMPLEN], tmp[MAILTMPLEN];
++ char realname[MAILTMPLEN], realpat[MAILTMPLEN] = {'\0'};
++ int i, found;
++ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL), j;
++ char *maildirpath = mdirpath();
++ COURIER_S *cdir;
++
++ if(!strpbrk(pat,"%*")){ /* a mailbox */
++ maildir_file_path(pat, curdir);
++ i = strlen(curdir) - 1;
++ if(curdir[i] == '/')
++ curdir[i] = '\0';
++ cdir = courier_list_dir(curdir);
++ if(cdir){
++ found = 0; j = 0L;
++ if(maildir_valid_name(pat)){
++ for(i = 0; !found && i < cdir->total; i++)
++ if(strstr(curdir, cdir->data[i]->name)){
++ if(strlen(curdir) < strlen(cdir->data[i]->name))
++ found += 2;
++ else if(strlen(curdir) == strlen(cdir->data[i]->name))
++ found -= 1;
++ }
++ if(found > 0)
++ j = LATT_HASCHILDREN;
++ else if(found == 0)
++ j = (style == COURIER) ? LATT_HASNOCHILDREN : LATT_NOINFERIORS;
++ }
++ else
++ j = LATT_NOSELECT;
++ j += maildir_any_new_msgs(curdir) ? LATT_MARKED : LATT_UNMARKED;
++ if (found)
++ mm_list (stream, '.', pat, j);
++ courier_free_cdir(&cdir);
++ }
++ return;
++ }
++
++ strcpy(tmp,pat + 4); /* a directory */
++ j = strlen(pat) - 1;
++ maildir_file_path(pat, realpat);
++ c = pat[j];
++ pat[j] = '\0';
++ realname[0] = '\0';
++ if(dir)
++ maildir_file_path(dir, realname);
++ sprintf(curdir,"%s%s%s/%s", (dir ? "" : myrootdir(pat)), (dir ? "" : "/"),
++ (dir ? realname : maildirpath), (dir ? "" : "."));
++ sprintf(tmp, "%s%s/.", MDPREFIX(COURIER), dir ? dir : maildirpath);
++ if (level == 0 && tmp && pmatch_full (tmp, realpat, '.'))
++ mm_list (stream,'.', tmp, LATT_NOSELECT);
++
++ cdir = courier_list_dir(pat);
++ pat[j] = c;
++ for (i = 0; cdir && i < cdir->total; i++)
++ if(pmatch_full (cdir->data[i]->name, pat, '.')){
++ sprintf(tmp, "%s.", cdir->data[i]->name);
++ courier_list_info(&cdir, tmp, i);
++ mm_list (stream,'.',cdir->data[i]->name, cdir->data[i]->attribute);
++ }
++ courier_free_cdir(&cdir);
++ }
++
++ int
++ same_maildir_file(char *name1, char *name2)
++ {
++ char tmp1[MAILTMPLEN], tmp2[MAILTMPLEN];
++ char *s;
++
++ strcpy(tmp1, name1 ? name1 : "");
++ strcpy(tmp2, name2 ? name2 : "");
++ if ((s = strrchr(tmp1, FLAGSEP)) != NULL)
++ *s = '\0';
++ if (((s = strrchr(tmp1, SIZESEP)) != NULL) && (strchr(s,'.') == NULL))
++ *s = '\0';
++ if ((s = strrchr(tmp2, FLAGSEP)) != NULL)
++ *s = '\0';
++ if (((s = strrchr(tmp2, SIZESEP)) != NULL) && (strchr(s,'.') == NULL))
++ *s = '\0';
++
++ return !strcmp(tmp1, tmp2);
++ }
++
++ unsigned long antoul(char *seed)
++ {
++ int i, error = 0;
++ unsigned long val = 0L, rv1 = 0L, t;
++ char c, *p;
++ if(!seed)
++ return 0L;
++ t = strtoul(seed, &p, 10);
++ if(p && (*p == '.' || *p == '_'))
++ return t;
++ /* else */
++ if((p = strchr(seed,'.')) != NULL)
++ *p = '\0';
++ error = (strlen(seed) > 6); /* too long */
++ for(i= strlen(seed)-1; error == 0 && i >= 0; i--){
++ c = seed[i];
++ if (c >= 'A' && c <= 'Z') val = c - 'A';
++ else if (c >= 'a' && c <= 'z') val = c - 'a' + 26;
++ else if (c >= '0' && c <= '9') val = c - '0' + 26 + 26;
++ else if (c == '-') val = c - '-' + 26 + 26 + 10;
++ else if (c == '_') val = c - '_' + 26 + 26 + 10 + 1;
++ else error++;
++ rv1 = val + (rv1 << 6);
++ }
++ if(p)
++ *p = '.';
++ return error ? 0L : rv1;
++ }
++
++ unsigned long mdfntoul (char *name)
++ {
++ unsigned long t;
++ char *r, last;
++
++ if((*name == '_') && ((r = strpbrk(name,".,%+")) != NULL)){ /* Grrr!!! */
++ last = *r;
++ *r = '\0';
++ t = antoul(r+1);
++ *r = last;
++ }
++ else
++ t = antoul(name);
++ return t;
++ }
++
++ int comp_maildir_file(char *name1, char *name2)
++ {
++ int uset1 = 1, uset2 = 1, i, j, cmp;
++ unsigned long t1, t2;
++ char *s1, *s2;
++
++ if (!(name1 && *name1))
++ return (name2 && *name2) ? (*name2 == FLAGSEP ? 0 : -1) : 0;
++
++ if (!(name2 && *name2))
++ return (name1 && *name1) ? (*name1 == FLAGSEP ? 0 : 1) : 0;
++
++ if((cmp = strcmp(name1,name2)) == 0)
++ return 0;
++
++ t1 = strtoul(name1, &s1, 10);
++ t2 = strtoul(name2, &s2, 10);
++
++ if(!s1 || *s1 != '.')
++ uset1 = 0;
++
++ if(!s2 || *s2 != '.')
++ uset2 = 0;
++
++ if(uset1 && uset2) /* normal sort order */
++ return (t1 < t2) ? -1 : (t1 > t2 ? 1 : (cmp < 0 ? -1 : 1));
++
++ /* If we make it here we say Grrrr.... first, then we try to figure out
++ * how to sort this mess.
++ * These are the rules.
++ * If there is a number at the beginning it is bigger than anything else.
++ * If there are digits, then the number of digits decides which one is bigger.
++ */
++
++ for(i = 0; isdigit(name1[i]); i++);
++ for(j = 0; isdigit(name2[j]); j++);
++
++ return(uset1 ? 1
++ : (uset2 ? -1
++ : (i < j ? -1 : (i > j ? 1 : (cmp < 0 ? -1 : 1)))));
++ }
++
++ void
++ maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t)
++ {
++ char tmp[MAILTMPLEN], *b;
++ int offset = 0;
++ int tmpd, tmpf, tmpr, tmps, tmpt;
++
++ if(d) *d = 0;
++ if(f) *f = 0;
++ if(r) *r = 0;
++ if(s) *s = 0;
++ if(t) *t = 0;
++
++ tmpd = tmpf = tmpr = tmps = tmpt = NIL; /* no flags set by default */
++ strcpy(tmp,name);
++ while ((b = strrchr(tmp+offset, FLAGSEP)) != NULL){
++ char flag,last;
++ int k;
++ if (!++b) break;
++ switch (*b){
++ case '1':
++ case '2':
++ case '3': flag = *b; b += 2;
++ for (k = 0; b[k] && b[k] != FLAGSEP && b[k] != ','; k++);
++ last = b[k];
++ b[k] = '\0';
++ if (flag == '2' || flag == '3'){
++ tmpd = strchr (b, MDFLAGC(Draft)) ? T : NIL;
++ tmpf = strchr (b, MDFLAGC(Flagged)) ? T : NIL;
++ tmpr = strchr (b, MDFLAGC(Replied)) ? T : NIL;
++ tmps = strchr (b, MDFLAGC(Seen)) ? T : NIL;
++ tmpt = strchr (b, MDFLAGC(Trashed)) ? T : NIL;
++ }
++ b[k] = last;
++ b += k;
++ for (; tmp[offset] && tmp[offset] != FLAGSEP; offset++);
++ offset++;
++ break;
++ default: break; /* Should we crash?... Nahhh */
++ }
++ }
++ if(d) *d = tmpd;
++ if(f) *f = tmpf;
++ if(r) *r = tmpr;
++ if(s) *s = tmps;
++ if(t) *t = tmpt;
++ }
++
++ int
++ maildir_message_in_list(char *msgname, struct direct **names,
++ unsigned long bottom, unsigned long top, unsigned long *pos)
++ {
++ unsigned long middle = (bottom + top)/2;
++ int test;
++
++ if (!msgname)
++ return NIL;
++
++ if (pos) *pos = middle;
++
++ if (same_maildir_file(msgname, names[middle]->d_name))
++ return T;
++
++ if (middle == bottom){ /* 0 <= 0 < 1 */
++ int rv = NIL;
++ if (same_maildir_file(msgname, names[middle]->d_name)){
++ rv = T;
++ if (pos) *pos = middle;
++ }
++ else
++ if (same_maildir_file(msgname, names[top]->d_name)){
++ rv = T;
++ if (pos) *pos = top;
++ }
++ return rv;
++ }
++
++ test = comp_maildir_file(msgname, names[middle]->d_name);
++
++ if (top <= bottom)
++ return test ? NIL : T;
++
++ if (test < 0 ) /* bottom < msgname < middle */
++ return maildir_message_in_list(msgname, names, bottom, middle, pos);
++ else if (test > 0) /* middle < msgname < top */
++ return maildir_message_in_list(msgname, names, middle, top, pos);
++ else return T;
++ }
++
++ void
++ maildir_abort(MAILSTREAM *stream)
++ {
++ if (LOCAL){
++ if(LOCAL->candouid)
++ maildir_read_uid(stream, NULL, &stream->uid_validity);
++ if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);
++ if (LOCAL->curdir) fs_give ((void **) &LOCAL->curdir);
++ if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
++ if(LOCAL->uidtempfile){
++ unlink(LOCAL->uidtempfile);
++ fs_give ((void **) &LOCAL->uidtempfile);
++ }
++ fs_give ((void **) &stream->local);
++ }
++ if (mdfpath) fs_give((void **)&mdfpath);
++ stream->dtb = NIL;
++ }
++
++ int
++ maildir_contains_folder(char *dirname, char *name)
++ {
++ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN];
++ int rv = 0;
++ DIR *dir;
++ struct direct *d;
++
++ maildir_file_path(dirname, tmp2);
++ if(name){
++ strcat(tmp2,"/");
++ strcat(tmp2, name);
++ }
++
++ if (!(dir = opendir (tmp2)))
++ return NIL;
++
++ while ((d = readdir(dir)) != NULL){
++ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
++ && strcmp(d->d_name, MDNAME(Cur))
++ && strcmp(d->d_name, MDNAME(Tmp))
++ && strcmp(d->d_name, MDNAME(New))){
++
++ sprintf(tmp,"%s/%s", tmp2, d->d_name);
++ if(maildir_valid(tmp)){
++ rv++;
++ break;
++ }
++ }
++ }
++ closedir(dir);
++ return rv;
++ }
++
++ int
++ maildir_is_dir(char *dirname, char *name)
++ {
++ char tmp[MAILTMPLEN];
++ struct stat sbuf;
++
++ maildir_file_path(dirname, tmp);
++ if(name){
++ strcat(tmp,"/");
++ strcat(tmp,name);
++ }
++ strcat(tmp,"/");
++ strcat(tmp,MDDIR);
++
++ return ((stat(tmp, &sbuf) == 0) && S_ISREG (sbuf.st_mode)) ? 1 : 0;
++ }
++
++ int
++ maildir_dir_is_empty(char *mailbox)
++ {
++ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], tmp3[MAILTMPLEN],*s;
++ int rv = 1, courier = IS_COURIER(mailbox);
++ DIR *dir;
++ struct direct *d;
++ struct stat sbuf;
++
++ maildir_file_path(mailbox, tmp2);
++
++ if(courier){
++ strcpy(tmp3, tmp2);
++ if(s = strrchr(tmp2, '/'))
++ *s = '\0';
++ }
++
++ if (!(dir = opendir (tmp2)))
++ return rv;
++
++ if(courier){
++ while((d = readdir(dir)) != NULL){
++ sprintf(tmp,"%s/%s", tmp2, d->d_name);
++ if(!strncmp(tmp, tmp3, strlen(tmp3))
++ && tmp[strlen(tmp3)] == '.'){
++ rv = 0;
++ break;
++ }
++ }
++ }
++ else
++ while ((d = readdir(dir)) != NULL){
++ sprintf(tmp,"%s/%s", tmp2, d->d_name);
++ if (strcmp(d->d_name, ".")
++ && strcmp(d->d_name,"..")
++ && strcmp(d->d_name, MDNAME(Cur))
++ && strcmp(d->d_name, MDNAME(Tmp))
++ && strcmp(d->d_name, MDNAME(New))
++ && strcmp(d->d_name, MDDIR)
++ && strcmp(d->d_name, MDUIDVALIDITY)
++ && !(d->d_name[0] == '.'
++ && stat (tmp,&sbuf) == 0
++ && S_ISREG(sbuf.st_mode))){
++ rv = 0;
++ break;
++ }
++ }
++ closedir(dir);
++ return rv;
++ }
++
++ void
++ maildir_get_file (MAILDIRFILE **mdfile)
++ {
++ MAILDIRFILE *md;
++
++ md = (MAILDIRFILE *) fs_get(sizeof(MAILDIRFILE));
++ memset(md, 0, sizeof(MAILDIRFILE));
++ *mdfile = md;
++ }
++
++ void
++ maildir_free_file (void **mdfile)
++ {
++ MAILDIRFILE *md = (mdfile && *mdfile) ? (MAILDIRFILE *) *mdfile : NULL;
++
++ if (md){
++ if (md->name) fs_give((void **)&md->name);
++ fs_give((void **)&md);
++ }
++ }
++
++ void
++ maildir_free_file_only (void **mdfile)
++ {
++ MAILDIRFILE *md = (mdfile && *mdfile) ? (MAILDIRFILE *) *mdfile : NULL;
++
++ if (md && md->name)
++ fs_give((void **)&md->name);
++ }
++
++ int
++ maildir_any_new_msgs(char *mailbox)
++ {
++ char tmp[MAILTMPLEN];
++ int rv = NIL;
++ DIR *dir;
++ struct direct *d;
++
++ MDFLD(tmp, mailbox, New);
++
++ if (!(dir = opendir (tmp)))
++ return rv;
++
++ while ((d = readdir(dir)) != NULL){
++ if (d->d_name[0] == '.')
++ continue;
++ rv = T;
++ break;
++ }
++ closedir(dir);
++ return rv;
++ }
++
++
++ void
++ maildir_get_date(MAILSTREAM *stream, unsigned long msgno)
++ {
++ MESSAGECACHE *elt;
++ struct tm *t;
++ time_t ti;
++ int i,k;
++
++ elt = mail_elt (stream,msgno);
++ if(elt && elt->year != 0)
++ return;
++ if ((ti = mdfntoul(MDFILE(elt))) > 0L && (t = gmtime(&ti))){
++ i = t->tm_hour * 60 + t->tm_min;
++ k = t->tm_yday;
++ t = localtime(&ti);
++ i = t->tm_hour * 60 + t->tm_min - i;
++ if((k = t->tm_yday - k) != 0)
++ i += ((k < 0) == (abs (k) == 1)) ? -24*60 : 24*60;
++ k = abs (i);
++ elt->hours = t->tm_hour;
++ elt->minutes = t->tm_min;
++ elt->seconds = t->tm_sec;
++ elt->day = t->tm_mday; elt->month = t->tm_mon + 1;
++ elt->year = t->tm_year - (BASEYEAR - 1900);
++ elt->zoccident = (k == i) ? 0 : 1;
++ elt->zhours = k/60;
++ elt->zminutes = k % 60;
++ }
++ }
++
++ /* Support for Courier Style directories
++ When this code is complete there will be two types of support, which
++ will be configurable. The problem is the following: In Courier style
++ folder structure, a "folder" may have a subfolder called
++ "folder.subfolder", which is not natural in the file system in the
++ sense that I can not stat for "folder.subfolder" wihtout knowing what
++ "subfolder" is. It needs to be guessed. Because of this I need to look
++ in the list of folders if there is a folder with a name
++ "folder.subfolder", before I can say if the folder is dual or not. One
++ can avoid this annoyance if one ignores the problem by declaring that
++ every folder is dual. I will however code as the default the more
++ complicated idea of scaning the containing directory each time it is
++ modified and search for subfolders, and list the entries it found.
++ */
++
++ int courier_dir_select (const struct direct *name)
++ {
++ return name->d_name[0] == '.' && (strlen(name->d_name) > 2
++ || (strlen(name->d_name) == 2 && name->d_name[1] != '.'));
++ }
++
++ int courier_dir_sort (const void *d1, const void *d2)
++ {
++ const struct direct *e1 = *(const struct direct **) d1;
++ const struct direct *e2 = *(const struct direct **) d2;
++
++ return strcmp((char *) e1->d_name, (char *) e2->d_name);
++ }
++
++ void courier_free_cdir (COURIER_S **cdir)
++ {
++ int i;
++
++ if (!*cdir)
++ return;
++
++ if ((*cdir)->path) fs_give((void **)&((*cdir)->path));
++ for (i = 0; i < (*cdir)->total; i++)
++ if((*cdir)->data[i]->name) fs_give((void **)&((*cdir)->data[i]->name));
++ fs_give((void **)&((*cdir)->data));
++ fs_give((void **)&(*cdir));
++ }
++
++ COURIER_S *courier_get_cdir (int total)
++ {
++ COURIER_S *cdir;
++
++ cdir = (COURIER_S *)fs_get(sizeof(COURIER_S));
++ memset(cdir, 0, sizeof(COURIER_S));
++ cdir->data = (COURIERLOCAL **) fs_get(total*sizeof(COURIERLOCAL *));
++ memset(cdir->data, 0, sizeof(COURIERLOCAL *));
++ cdir->total = total;
++ return cdir;
++ }
++
++ int courier_search_list(COURIERLOCAL **data, char *name, int first, int last)
++ {
++ int try = (first + last)/2;
++
++ if(!strstr(data[try]->name, name)){
++ if(first == try) /* first == last || first + 1 == last */
++ return strstr(data[last]->name, name) ? 1 : 0;
++ if(strcmp(data[try]->name, name) < 0) /*data[try] < name < data[end] */
++ return courier_search_list(data, name, try, last);
++ else /* data[begin] < name < data[try] */
++ return courier_search_list(data, name, first, try);
++ }
++ return 1;
++ }
++
++ /* Lists all directories that are subdirectories of a given directory */
++
++ COURIER_S *courier_list_dir(char *curdir)
++ {
++ struct direct **names = NIL;
++ struct stat sbuf;
++ unsigned long ndir;
++ COURIER_S *cdir = NULL;
++ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], pathname[MAILTMPLEN],
++ realname[MAILTMPLEN];
++ int i, j, scand, td;
++
++ /* There are two cases, either curdir is
++ #mc/INBOX. #mc/INBOX.foo
++ or
++ #mc/Maildir/. #mc/Maildir/.foo
++ */
++ strcpy(tmp,curdir + 4);
++ if(!strncmp(ucase(tmp), "INBOX", 5))
++ strcpy(tmp, "#mc/INBOX.");
++ else{
++ strcpy(tmp, curdir);
++ for (i = strlen(tmp) - 1; tmp[i] && tmp[i] != '/'; i--);
++ tmp[i+2] = '\0'; /* keep the last "." intact */
++ }
++ maildir_file_path(tmp, realname);
++ maildir_scandir (realname, &names, &ndir, &scand, COURIER);
++
++ if (scand > 0){
++ cdir = courier_get_cdir(ndir);
++ cdir->path = cpystr(realname);
++ for(i = 0, j = 0; i < ndir; i++){
++ td = realname[strlen(realname) - 1] == '.'
++ && *names[i]->d_name == '.';
++ sprintf(tmp2,"%s%s", tmp, names[i]->d_name+1);
++ sprintf(pathname,"%s%s", realname, names[i]->d_name + td);
++ if(stat(pathname, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)){
++ cdir->data[j] = (COURIERLOCAL *) fs_get(sizeof(COURIERLOCAL));
++ cdir->data[j++]->name = cpystr(tmp2);
++ }
++ fs_give((void **)&names[i]);
++ }
++ cdir->total = j;
++ if(cdir->total == 0)
++ courier_free_cdir(&cdir);
++ }
++ if(names)
++ fs_give((void **) &names);
++ return cdir;
++ }
++
++ void
++ courier_list_info(COURIER_S **cdirp, char *data, int i)
++ {
++ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL);
++ COURIER_S *cdir = *cdirp;
++
++ if(maildir_valid(cdir->data[i]->name)){
++ if(courier_search_list(cdir->data, data, 0, cdir->total - 1))
++ cdir->data[i]->attribute = LATT_HASCHILDREN;
++ else
++ cdir->data[i]->attribute = (style == COURIER)
++ ? LATT_HASNOCHILDREN : LATT_NOINFERIORS;
++ }
++ else
++ cdir->data[i]->attribute = LATT_NOSELECT;
++ cdir->data[i]->attribute += maildir_any_new_msgs(cdir->data[i]->name)
++ ? LATT_MARKED : LATT_UNMARKED;
++ }
++
++ /* UID Support */
++ /* Yes, I know I procastinated a lot about this, but here it is finally */
++
++ unsigned int
++ maildir_can_assign_uid (MAILSTREAM *stream)
++ {
++ unsigned int rv = 0;
++ int createtemp;
++ unsigned long t;
++ char tmp[MAILTMPLEN], *s;
++ DIR *dir;
++ struct direct *d;
++
++ if(!stream || stream->rdonly
++ || !LOCAL || !LOCAL->dir || !(dir = opendir(LOCAL->dir)))
++ return rv;
++
++ sprintf(tmp, "%s.%d", MDUIDTEMP, mypid);
++ while ((d = readdir(dir)) != NULL){
++ if(!strncmp(d->d_name, tmp, strlen(tmp))
++ || !strncmp(d->d_name, MDUIDTEMP, strlen(MDUIDTEMP)))
++ break;
++ }
++ rv = d ? !strncmp(d->d_name, tmp, strlen(tmp)) : 1;
++ createtemp = d ? 0 : 1;
++ if (d && rv == 0){ /* is there a temp file that is not ours? */
++ s = strrchr(d->d_name, '.');
++ t = strtoul(s+1, &s, 10);
++ if(s != NULL && *s != '\0')
++ createtemp++;
++ if(time(0) > t + MAXTEMPUID){
++ createtemp++;
++ sprintf(tmp,"%s/%s", LOCAL->dir, d->d_name);
++ unlink(tmp);
++ }
++ }
++ closedir(dir);
++ if(createtemp){
++ FILE *fp;
++ sprintf(tmp,"%s/%s.%d.%lu", LOCAL->dir, MDUIDTEMP, mypid, time(0));
++ if(fp = fopen(tmp, "w")){
++ fclose(fp);
++ if(LOCAL->uidtempfile)
++ fs_give((void **)&LOCAL->uidtempfile);
++ LOCAL->uidtempfile = cpystr(tmp);
++ rv++;
++ }
++ }
++ return rv;
++ }
++
++ void
++ maildir_read_uid(MAILSTREAM *stream, unsigned long *uid_last,
++ unsigned long *uid_validity)
++ {
++ int createuid, deleteuid = 0;
++ char tmp[MAILTMPLEN], *s = NULL;
++ DIR *dir;
++ struct direct *d;
++
++ if(uid_last) *uid_last = 0L;
++ if(uid_last && uid_validity) *uid_validity = time(0);
++ if(!stream || !LOCAL || !LOCAL->dir || !(dir = opendir(LOCAL->dir)))
++ return;
++
++ while ((d = readdir(dir)) != NULL){
++ if(!strncmp(d->d_name, MDUIDLAST, strlen(MDUIDLAST)))
++ break;
++ }
++ createuid = d == NULL ? 1 : 0;
++ if(uid_last == NULL)
++ deleteuid++;
++ if(d){
++ if(uid_last){
++ s = d->d_name + strlen(MDUIDLAST) + 1;
++ *uid_last = strtoul(s, &s, 10);
++ if(!s || *s != '.'){
++ deleteuid++;
++ createuid++;
++ *uid_last = 0L;
++ }
++ }
++ if(s && *s == '.'){
++ if(uid_validity){
++ s++;
++ *uid_validity = strtoul(s, &s, 10);
++ if(s && *s != '\0'){
++ *uid_validity = time(0);
++ deleteuid++;
++ createuid++;
++ }
++ }
++ }
++ else{
++ deleteuid++;
++ createuid++;
++ }
++ }
++ if(deleteuid){
++ sprintf(tmp,"%s/%s", LOCAL->dir, d->d_name);
++ unlink(tmp);
++ }
++ if(createuid)
++ maildir_write_uid(stream, (uid_last ? *uid_last : stream->uid_last),
++ uid_validity ? *uid_validity : time(0));
++ closedir(dir);
++ }
++
++ void
++ maildir_write_uid(MAILSTREAM *stream, unsigned long uid_last,
++ unsigned long uid_validity)
++ {
++ char tmp[MAILTMPLEN];
++ FILE *fp;
++
++ if(!stream || stream->rdonly || !LOCAL || !LOCAL->dir)
++ return;
++
++ sprintf(tmp,"%s/%s.%010lu.%010lu", LOCAL->dir, MDUIDLAST,
++ uid_last, uid_validity);
++ if(fp = fopen(tmp, "w"))
++ fclose(fp);
++ }
++
++ unsigned long
++ maildir_get_uid(char *name)
++ {
++ char *s;
++ unsigned long rv = 0L;
++
++ if(!name || (s = strstr(name,MDUIDSEP)) == NULL)
++ return rv;
++
++ s += strlen(MDUIDSEP);
++ rv = strtoul(s, NULL, 10);
++ return rv;
++ }
++
++
++ void
++ maildir_delete_uid(MAILSTREAM *stream, unsigned long msgno)
++ {
++ char old[MAILTMPLEN], new[MAILTMPLEN], *s, *t;
++ MESSAGECACHE *elt;
++
++ elt = mail_elt(stream, msgno);
++ if(!stream || !elt || !elt->private.spare.ptr || !LOCAL || !LOCAL->dir)
++ return;
++
++ sprintf(old, "%s/%s/%s", LOCAL->dir, MDNAME(Cur), MDFILE(elt));
++ t = MDFILE(elt);
++ if(s = strstr(MDFILE(elt), MDUIDSEP)){
++ *s = '\0';
++ s += strlen(MDUIDSEP);
++ strtoul(s, &s, 10);
++ sprintf(new, "%s/%s/%s%s", LOCAL->dir, MDNAME(Cur), t, s);
++ if(rename(old, new) == 0){
++ maildir_free_file_only ((void **)&elt->private.spare.ptr);
++ s = strrchr(new, '/');
++ MDFILE(elt) = cpystr(s+1);
++ }
++ elt->private.uid = 0L;
++ }
++ }
++
++ void
++ maildir_assign_uid(MAILSTREAM *stream, unsigned long msgno, unsigned long uid)
++ {
++ int createuid, deleteuid = 0;
++ char old[MAILTMPLEN], new[MAILTMPLEN], *s, *t;
++ MESSAGECACHE *elt;
++
++ elt = mail_elt(stream, msgno);
++ if(!stream || !elt || !elt->private.spare.ptr || !LOCAL || !LOCAL->dir)
++ return;
++
++ maildir_delete_uid(stream, msgno);
++ sprintf(old, "%s/%s/%s", LOCAL->dir, MDNAME(Cur), MDFILE(elt));
++ t = MDFILE(elt);
++ if((s = strrchr(MDFILE(elt),FLAGSEP)) != NULL){
++ *s++ = '\0';
++ sprintf(new, "%s/%s/%s%s%lu%c%s",
++ LOCAL->dir, MDNAME(Cur), t, MDUIDSEP, uid, FLAGSEP, s);
++ if(rename(old, new) == 0){
++ maildir_free_file_only ((void **)&elt->private.spare.ptr);
++ s = strrchr(new, '/');
++ MDFILE(elt) = cpystr(s+1);
++ stream->uid_validity = time(0);
++ }
++ elt->private.uid = uid;
++ }
++ }
++
++ void
++ maildir_uid_renew_tempfile(MAILSTREAM *stream)
++ {
++ char tmp[MAILTMPLEN];
++
++ if(!stream || stream->rdonly
++ || !LOCAL || !LOCAL->candouid || !LOCAL->dir || !LOCAL->uidtempfile)
++ return;
++
++ sprintf(tmp,"%s/%s.%d.%lu", LOCAL->dir, MDUIDTEMP, mypid, time(0));
++ if(rename(LOCAL->uidtempfile, tmp) == 0){
++ fs_give((void **)&LOCAL->uidtempfile);
++ LOCAL->uidtempfile = cpystr(tmp);
++ }
++ }
+diff -rc alpine-2.00/imap/src/osdep/unix/maildir.h alpine-2.00.maildir/imap/src/osdep/unix/maildir.h
+*** alpine-2.00/imap/src/osdep/unix/maildir.h 2011-01-24 19:38:50.000000000 -0600
+--- alpine-2.00.maildir/imap/src/osdep/unix/maildir.h 2011-01-15 19:11:36.000000000 -0600
+***************
+*** 0 ****
+--- 1,226 ----
++ /*
++ * A few definitions that try to make this module portable to other
++ * platforms (e.g. Cygwin). This module is based on the information from
++ * http://cr.yp.to/proto/maildir.html
++ */
++
++ /* First we deal with the separator character */
++ #ifndef FLAGSEP
++ #define FLAGSEP ':'
++ #endif
++ #define SIZESEP ','
++
++ const char sep1[] = {FLAGSEP, '1', ',', '\0'}; /* experimental semantics*/
++ const char sep2[] = {FLAGSEP, '2', ',', '\0'}; /* Flags Information */
++ const char sep3[] = {FLAGSEP, '3', ',', '\0'}; /* Grrrr.... */
++
++ const char *sep[] = { sep1, sep2, sep3, NULL};
++
++ #define MDSEP(i) sep[((i) - 1)]
++
++ /* Now we deal with flags. Woohoo! */
++ typedef enum {Draft, Flagged, Passed, Replied, Seen, Trashed,
++ EmptyFlag, EndFlags} MdFlagNamesType;
++ const int mdimapflags[] = {Draft, Flagged, Replied, Seen, Trashed, EmptyFlag, EndFlags};
++ const int mdkwdflags[] = {Passed, EmptyFlag, EndFlags};
++
++ /* this array lists the codes for mdflgnms (maildir flag names) above */
++ const char *mdflags[] = { "D", "F", "P", "R", "S", "T", "", NULL};
++ /* and as characters too */
++ const char cmdflags[] = { 'D', 'F', 'P', 'R', 'S', 'T', '0', '\0'};
++
++ /* MDFLAG(Seen, elt->seen) */
++ #define MDFLAG(i,j) mdflags[j ? (i) : EmptyFlag]
++ /* MDFLAGC(Seen) */
++ #define MDFLAGC(i) cmdflags[(i)]
++
++ /* Now we deal with the directory structure */
++ typedef enum {Cur, Tmp, New, EndDir} DirNamesType;
++ char *mdstruct[] = {"cur", "tmp", "new", NULL};
++ #define MDNAME(i) mdstruct[(i)]
++ #define MDFLD(tmp, dir, i) sprintf((tmp),"%s/%s", (dir), mdstruct[(i)])
++ #define MSGPATH(tmp, dir, msg,i) sprintf((tmp),"%s/%s/%s", (dir), mdstruct[(i)],(msg))
++
++ /* Files associated to a maildir directory */
++
++ #define MDUIDVALIDITY ".uidvalidity" /* support for old maildirs */
++ #define MDDIR ".mdir" /* this folder is a directory */
++ #define MDUIDLAST ".uidlast" /* last assigned uid */
++ #define MDUIDTEMP ".uidtemp" /* We assign uid's no one else */
++
++
++
++ /* Support of Courier Structure */
++ #define CCLIENT 0
++ #define COURIER 1
++ #define IS_CCLIENT(t) \
++ (((t) && (t)[0] == '#' && ((t)[1] == 'm' || (t)[1] == 'M')\
++ && ((t)[2] == 'd' || (t)[2] == 'D')\
++ && (t)[3] == '/' && (t)[4] != '\0') ? 1 : 0)
++
++ #define IS_COURIER(t) \
++ (((t) && (t)[0] == '#' && ((t)[1] == 'm' || (t)[1] == 'M')\
++ && ((t)[2] == 'c' || (t)[2] == 'C')\
++ && (t)[3] == '/' && (t)[4] != '\0') ? 1 : 0)
++ #define MDPREFIX(s) ((s) ? "#mc/" : "#md/")
++ #define MDSEPARATOR(s) ((s) ? '.' : '/')
++
++ /* UID Support */
++
++ #define MAXTEMPUID (unsigned long) 180L
++ const char mduid[] = {',','u','=','\0'};
++ #define MDUIDSEP mduid
++
++
++ /* Now we deal with messages filenames */
++ char mdlocaldomain[MAILTMPLEN+1] = {'\0'};
++ pid_t mypid = (pid_t) 0;
++ static char *mdfpath = NULL;
++ static char myMdInboxDir[50] = { '\0' };/* Location of the Maildir INBOX */
++ static long CourierStyle = CCLIENT;
++
++ #define CHUNK 16384 /* from unix.h */
++
++ typedef struct courier_local {
++ char *name; /* name of directory/folder */
++ int attribute; /* attributes (children/marked/etc) */
++ } COURIERLOCAL;
++
++ typedef struct courier {
++ char *path; /* Path to collection */
++ time_t scantime; /* time at which information was generated */
++ int total; /* total number of elements in data */
++ COURIERLOCAL **data;
++ } COURIER_S;
++
++ /* In gdb this is the *(struct maildir_local *)stream->local structure */
++ typedef struct maildir_local {
++ unsigned int dirty : 1; /* diskcopy needs updating */
++ unsigned int courier : 1; /* It is Courier style file system */
++ unsigned int link : 1; /* There is a symbolic link */
++ unsigned int candouid; /* we can assign uids and no one else */
++ char *uidtempfile; /* path to uid temp file */
++ int fd; /* fd of open message */
++ char *dir; /* mail directory name */
++ char *curdir; /* mail directory name/cur */
++ unsigned char *buf; /* temporary buffer */
++ unsigned long buflen; /* current size of temporary buffer */
++ time_t scantime; /* last time directory scanned */
++ } MAILDIRLOCAL;
++
++ /* Convenient access to local data */
++ #define LOCAL ((MAILDIRLOCAL *) stream->local)
++
++ typedef struct maildir_file_info {
++ char *name; /* name of the file */
++ DirNamesType loc; /* location of this file */
++ unsigned long pos; /* place in list where this file is listed */
++ off_t size; /* size in bytes, on disk */
++ time_t atime; /* last access time */
++ time_t mtime; /* last modified time */
++ time_t ctime; /* last changed time */
++ } MAILDIRFILE;
++
++ #define MDFILE(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->name)
++ #define MDLOC(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->loc)
++ #define MDPOS(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->pos)
++ #define MDSIZE(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->size)
++ #define MDATIME(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->atime)
++ #define MDMTIME(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->mtime)
++ #define MDCTIME(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->ctime)
++
++ /* Function prototypes */
++
++ DRIVER *maildir_valid (char *name);
++ MAILSTREAM *maildir_open (MAILSTREAM *stream);
++ void maildir_close (MAILSTREAM *stream, long options);
++ long maildir_ping (MAILSTREAM *stream);
++ void maildir_check (MAILSTREAM *stream);
++ long maildir_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);
++ char *maildir_header (MAILSTREAM *stream,unsigned long msgno,
++ unsigned long *length, long flags);
++ void maildir_list (MAILSTREAM *stream,char *ref,char *pat);
++ void *maildir_parameters (long function,void *value);
++ int maildir_create_folder (char *mailbox);
++ long maildir_create (MAILSTREAM *stream,char *mailbox);
++ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt); /*check */
++ long maildir_expunge (MAILSTREAM *stream, char *sequence, long options);
++ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);
++ long maildir_append (MAILSTREAM *stream,char *mailbox, append_t af, void *data);
++ long maildir_delete (MAILSTREAM *stream,char *mailbox);
++ long maildir_rename (MAILSTREAM *stream,char *old,char *new);
++ long maildir_sub (MAILSTREAM *stream,char *mailbox);
++ long maildir_unsub (MAILSTREAM *stream,char *mailbox);
++ void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat);
++ void courier_list (MAILSTREAM *stream,char *ref, char *pat);
++
++ /* utility functions */
++ void courier_realname (char *name, char *realname);
++ long maildir_dirfmttest (char *name);
++ char *maildir_file (char *dst,char *name);
++ int maildir_select (const struct direct *name);
++ int maildir_namesort (const void *d1, const void *d2);
++ unsigned long antoul (char *seed);
++ unsigned long mdfntoul (char *name);
++ int courier_dir_select (const struct direct *name);
++ int courier_dir_sort (const void *d1, const void *d2);
++ long maildir_canonicalize (char *pattern,char *ref,char *pat);
++ void maildir_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level);
++ void courier_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level);
++ int maildir_file_path(char *name, char *tmp);
++ int maildir_valid_name (char *name);
++ int maildir_valid_dir (char *name);
++ int is_valid_maildir (char **name);
++ int maildir_message_exists(MAILSTREAM *stream,char *name, char *tmp);
++ char *maildir_remove_root(char *name);
++ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt, unsigned long *length,long flags);
++ unsigned long maildir_parse_message(MAILSTREAM *stream, unsigned long msgno,
++ DirNamesType dirtype);
++ int maildir_eliminate_duplicate (char *name, struct direct ***flist,
++ unsigned long *nfiles);
++ int maildir_doscandir (char *name, struct direct ***flist, int flag);
++ unsigned long maildir_scandir (char *name, struct direct ***flist,
++ unsigned long *nfiles, int *scand, int flag);
++ void maildir_parse_folder (MAILSTREAM *stream, int full);
++ void md_domain_name (void);
++ char *myrootdir (char *name);
++ char *mdirpath (void);
++ int maildir_initial_check (MAILSTREAM *stream, DirNamesType dirtype);
++ unsigned long maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs,
++ DirNamesType dirtype, struct direct **names, unsigned long nfiles, int full);
++ int same_maildir_file(char *name1, char *name2);
++ int comp_maildir_file(char *name1, char *name2);
++ int maildir_message_in_list(char *msgname, struct direct **names,
++ unsigned long bottom, unsigned long top, unsigned long *pos);
++ void maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t);
++ int maildir_update_elt_maildirp(MAILSTREAM *stream, unsigned long msgno);
++ void maildir_abort (MAILSTREAM *stream);
++ int maildir_contains_folder(char *dirname, char *name);
++ int maildir_is_dir(char *dirname, char *name);
++ int maildir_dir_is_empty(char *mailbox);
++ int maildir_create_work (char *mailbox, int loop);
++ void maildir_get_file (MAILDIRFILE **mdfile);
++ void maildir_free_file (void **mdfile);
++ void maildir_free_file_only (void **mdfile);
++ int maildir_any_new_msgs(char *mailbox);
++ void maildir_get_date(MAILSTREAM *stream, unsigned long msgno);
++ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags);
++
++ /* Courier server support */
++ void courier_free_cdir (COURIER_S **cdir);
++ COURIER_S *courier_get_cdir (int total);
++ int courier_search_list(COURIERLOCAL **data, char *name, int first, int last);
++ COURIER_S *courier_list_dir(char *curdir);
++ void courier_list_info(COURIER_S **cdirp, char *data, int i);
++
++ /* UID Support */
++ unsigned int maildir_can_assign_uid (MAILSTREAM *stream);
++ void maildir_read_uid(MAILSTREAM *stream, unsigned long *uid_last,
++ unsigned long *uid_validity);
++ void maildir_write_uid(MAILSTREAM *stream, unsigned long uid_last,
++ unsigned long uid_validity);
++ unsigned long maildir_get_uid(char *name);
++ void maildir_delete_uid(MAILSTREAM *stream, unsigned long msgno);
++ void maildir_assign_uid(MAILSTREAM *stream, unsigned long msgno, unsigned long uid);
++ void maildir_uid_renew_tempfile(MAILSTREAM *stream);
++
+diff -rc alpine-2.00/imap/src/osdep/unix/Makefile alpine-2.00.maildir/imap/src/osdep/unix/Makefile
+*** alpine-2.00/imap/src/osdep/unix/Makefile 2008-06-04 13:18:34.000000000 -0500
+--- alpine-2.00.maildir/imap/src/osdep/unix/Makefile 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 144,150 ****
+ # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
+ # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
+ #
+! DEFAULTDRIVERS=imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
+ CHUNKSIZE=65536
+
+ # Normally no need to change any of these
+--- 144,150 ----
+ # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
+ # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
+ #
+! DEFAULTDRIVERS=maildir courier imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
+ CHUNKSIZE=65536
+
+ # Normally no need to change any of these
+***************
+*** 153,159 ****
+ BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.o siglocal.o \
+ dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
+ rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
+! unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o
+ CFLAGS=-g
+
+ CAT=cat
+--- 153,159 ----
+ BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.o siglocal.o \
+ dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
+ rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
+! unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o maildir.o
+ CFLAGS=-g
+
+ CAT=cat
+***************
+*** 282,288 ****
+
+ cyg: # Cygwin - note that most local file drivers don't work!!
+ $(BUILD) `$(CAT) SPECIALS` OS=$@ \
+! DEFAULTDRIVERS="imap nntp pop3 mbx unix phile" \
+ SIGTYPE=psx CHECKPW=cyg LOGINPW=cyg CRXTYPE=std \
+ SPOOLDIR=/var \
+ ACTIVEFILE=/usr/local/news/lib/active \
+--- 282,288 ----
+
+ cyg: # Cygwin - note that most local file drivers don't work!!
+ $(BUILD) `$(CAT) SPECIALS` OS=$@ \
+! DEFAULTDRIVERS="imap nntp pop3 mbx unix maildir phile" \
+ SIGTYPE=psx CHECKPW=cyg LOGINPW=cyg CRXTYPE=std \
+ SPOOLDIR=/var \
+ ACTIVEFILE=/usr/local/news/lib/active \
+***************
+*** 892,898 ****
+ unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
+ utf8.o: mail.h misc.h osdep.h utf8.h tmap.c widths.c
+ utf8aux.o: mail.h misc.h osdep.h utf8.h
+!
+
+ # OS-dependent
+
+--- 892,898 ----
+ unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
+ utf8.o: mail.h misc.h osdep.h utf8.h tmap.c widths.c
+ utf8aux.o: mail.h misc.h osdep.h utf8.h
+! maildir.o: mail.h misc.h osdep.h maildir.h dummy.h
+
+ # OS-dependent
+
+diff -rc alpine-2.00/imap/src/osdep/unix/os_cyg.h alpine-2.00.maildir/imap/src/osdep/unix/os_cyg.h
+*** alpine-2.00/imap/src/osdep/unix/os_cyg.h 2008-06-04 13:18:34.000000000 -0500
+--- alpine-2.00.maildir/imap/src/osdep/unix/os_cyg.h 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 47,52 ****
+--- 47,53 ----
+ #define setpgrp setpgid
+
+ #define SYSTEMUID 18 /* Cygwin returns this for SYSTEM */
++ #define FLAGSEP ';'
+ #define geteuid Geteuid
+ uid_t Geteuid (void);
+
+diff -rc alpine-2.00/pith/conf.c alpine-2.00.maildir/pith/conf.c
+*** alpine-2.00/pith/conf.c 2008-08-22 19:07:05.000000000 -0500
+--- alpine-2.00.maildir/pith/conf.c 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 427,432 ****
+--- 427,435 ----
+
+ CONF_TXT_T cf_text_newsrc_path[] = "Full path and name of NEWSRC file";
+
++ #ifndef _WINDOWS
++ CONF_TXT_T cf_text_maildir_location[] = "Location relative to your HOME directory of the directory where your INBOX\n# for the maildir format is located. Default value is \"Maildir\". If your\n# inbox is located at \"~/Maildir\" you do not need to change this value.\n# A common value is also \".maildir\"";
++ #endif
+
+ /*----------------------------------------------------------------------
+ These are the variables that control a number of pine functions. They
+***************
+*** 627,632 ****
+--- 630,639 ----
+ NULL, cf_text_news_active},
+ {"news-spool-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
+ NULL, cf_text_news_spooldir},
++ #ifndef _WINDOWS
++ {"maildir-location", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
++ "Maildir Location", cf_text_maildir_location},
++ #endif
+ {"upload-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
+ NULL, cf_text_upload_cmd},
+ {"upload-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
+***************
+*** 2216,2221 ****
+--- 2223,2234 ----
+ mail_parameters(NULL, SET_NEWSSPOOL,
+ (void *)VAR_NEWS_SPOOL_DIR);
+
++ #ifndef _WINDOWS
++ set_current_val(&vars[V_MAILDIR_LOCATION], TRUE, TRUE);
++ if(VAR_MAILDIR_LOCATION && VAR_MAILDIR_LOCATION[0])
++ mail_parameters(NULL, SET_MDINBOXPATH, (void *)VAR_MAILDIR_LOCATION);
++ #endif
++
+ /* guarantee a save default */
+ set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE);
+ if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0])
+***************
+*** 2832,2837 ****
+--- 2845,2854 ----
+ F_SORT_DEFAULT_SAVE_ALPHA, h_config_sort_save_alpha, PREF_FLDR, 0},
+ {"vertical-folder-list", "Use Vertical Folder List",
+ F_VERTICAL_FOLDER_LIST, h_config_vertical_list, PREF_FLDR, 0},
++ #ifndef _WINDOWS
++ {"use-courier-folder-list", "Courier Style Folder List",
++ F_COURIER_FOLDER_LIST, h_config_courier_list, PREF_FLDR, 0},
++ #endif
+
+ /* Addr book */
+ {"combined-addrbook-display", "Combined Address Book Display",
+***************
+*** 6895,6900 ****
+--- 6912,6923 ----
+
+ break;
+
++ #ifndef _WINDOWS
++ case F_COURIER_FOLDER_LIST:
++ mail_parameters(NULL,SET_COURIERSTYLE,(void *)(F_ON(f->id ,ps)? 1 : 0));
++ break; /* COURIER == 1, CCLIENT == 0, see maildir.h */
++ #endif
++
+ case F_COLOR_LINE_IMPORTANT :
+ case F_DATES_TO_LOCAL :
+ clear_index_cache(ps->mail_stream, 0);
+***************
+*** 7676,7681 ****
+--- 7699,7708 ----
+ return(h_config_newmailwidth);
+ case V_NEWSRC_PATH :
+ return(h_config_newsrc_path);
++ #ifndef _WINDOWS
++ case V_MAILDIR_LOCATION :
++ return(h_config_maildir_location);
++ #endif
+ case V_BROWSER :
+ return(h_config_browser);
+ #if defined(DOS) || defined(OS2)
+diff -rc alpine-2.00/pith/conf.h alpine-2.00.maildir/pith/conf.h
+*** alpine-2.00/pith/conf.h 2008-08-19 19:27:11.000000000 -0500
+--- alpine-2.00.maildir/pith/conf.h 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 249,254 ****
+--- 249,258 ----
+ #define GLO_NEWS_ACTIVE_PATH vars[V_NEWS_ACTIVE_PATH].global_val.p
+ #define VAR_NEWS_SPOOL_DIR vars[V_NEWS_SPOOL_DIR].current_val.p
+ #define GLO_NEWS_SPOOL_DIR vars[V_NEWS_SPOOL_DIR].global_val.p
++ #ifndef _WINDOWS
++ #define VAR_MAILDIR_LOCATION vars[V_MAILDIR_LOCATION].current_val.p
++ #define GLO_MAILDIR_LOCATION vars[V_MAILDIR_LOCATION].global_val.p
++ #endif
+ #define VAR_DISABLE_DRIVERS vars[V_DISABLE_DRIVERS].current_val.l
+ #define VAR_DISABLE_AUTHS vars[V_DISABLE_AUTHS].current_val.l
+ #define VAR_REMOTE_ABOOK_METADATA vars[V_REMOTE_ABOOK_METADATA].current_val.p
+diff -rc alpine-2.00/pith/conftype.h alpine-2.00.maildir/pith/conftype.h
+*** alpine-2.00/pith/conftype.h 2008-08-19 19:27:11.000000000 -0500
+--- alpine-2.00.maildir/pith/conftype.h 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 114,119 ****
+--- 114,122 ----
+ , V_NEWSRC_PATH
+ , V_NEWS_ACTIVE_PATH
+ , V_NEWS_SPOOL_DIR
++ #ifndef _WINDOWS
++ , V_MAILDIR_LOCATION
++ #endif
+ , V_UPLOAD_CMD
+ , V_UPLOAD_CMD_PREFIX
+ , V_DOWNLOAD_CMD
+***************
+*** 380,385 ****
+--- 383,391 ----
+ F_PASS_C1_CONTROL_CHARS,
+ F_SINGLE_FOLDER_LIST,
+ F_VERTICAL_FOLDER_LIST,
++ #ifndef _WINDOWS
++ F_COURIER_FOLDER_LIST,
++ #endif
+ F_TAB_CHK_RECENT,
+ F_AUTO_REPLY_TO,
+ F_VERBOSE_POST,
+diff -rc alpine-2.00/pith/init.c alpine-2.00.maildir/pith/init.c
+*** alpine-2.00/pith/init.c 2007-08-16 17:25:10.000000000 -0500
+--- alpine-2.00.maildir/pith/init.c 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 407,412 ****
+--- 407,415 ----
+ && stricmp(filename, folder_base)){
+ #else
+ if(strncmp(filename, folder_base, folder_base_len) == 0
++ #ifndef _WINDOWS
++ && filename[folder_base_len] != list_cntxt->dir->delim
++ #endif
+ && strcmp(filename, folder_base)){
+ #endif
+ #endif
+diff -rc alpine-2.00/pith/pattern.c alpine-2.00.maildir/pith/pattern.c
+*** alpine-2.00/pith/pattern.c 2008-07-14 13:01:54.000000000 -0500
+--- alpine-2.00.maildir/pith/pattern.c 2011-01-24 19:38:41.000000000 -0600
+***************
+*** 5482,5487 ****
+--- 5482,5496 ----
+ break;
+
+ case '#':
++ #ifndef _WINDOWS
++ if(!struncmp(patfolder, "#md/", 4)
++ || !struncmp(patfolder, "#mc/", 4)){
++ maildir_file_path(patfolder, tmp1);
++ if(!strcmp(patfolder, stream->mailbox))
++ match++;
++ break;
++ }
++ #endif
+ if(!strcmp(patfolder, stream->mailbox))
+ match++;
+
+***************
+*** 7894,7900 ****
+ int we_cancel = 0, width;
+ CONTEXT_S *save_context = NULL;
+ char buf[MAX_SCREEN_COLS+1], sbuf[MAX_SCREEN_COLS+1];
+! char *save_ref = NULL;
+ #define FILTMSG_MAX 30
+
+ if(!stream)
+--- 7903,7909 ----
+ int we_cancel = 0, width;
+ CONTEXT_S *save_context = NULL;
+ char buf[MAX_SCREEN_COLS+1], sbuf[MAX_SCREEN_COLS+1];
+! char *save_ref = NULL, *save_dstfldr = NULL, *save_dstfldr2 = NULL;
+ #define FILTMSG_MAX 30
+
+ if(!stream)
+***************
+*** 7928,7933 ****
+--- 7937,7952 ----
+ if(F_OFF(F_QUELL_FILTER_MSGS, ps_global))
+ we_cancel = busy_cue(buf, NULL, 0);
+
++ #ifndef _WINDOWS
++ if(!struncmp(dstfldr, "#md/", 4) || !struncmp(dstfldr, "#mc/", 4)){
++ char tmp1[MAILTMPLEN];
++ maildir_file_path(dstfldr, tmp1);
++ save_dstfldr2 = dstfldr;
++ save_dstfldr = cpystr(tmp1);
++ dstfldr = save_dstfldr;
++ }
++ #endif
++
+ if(!is_absolute_path(dstfldr)
+ && !(save_context = default_save_context(ps_global->context_list)))
+ save_context = ps_global->context_list;
+***************
+*** 7991,7996 ****
+--- 8010,8020 ----
+ if(we_cancel)
+ cancel_busy_cue(buf[0] ? 0 : -1);
+
++ if(save_dstfldr){
++ fs_give((void **)&save_dstfldr);
++ dstfldr = save_dstfldr2;
++ }
++
+ return(buf[0] != '\0');
+ }
+
+diff -rc alpine-2.00/pith/pine.hlp alpine-2.00.maildir/pith/pine.hlp
+*** alpine-2.00/pith/pine.hlp 2008-08-22 19:07:05.000000000 -0500
+--- alpine-2.00.maildir/pith/pine.hlp 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 21253,21258 ****
+--- 21253,21354 ----
+ &lt;End of help on this topic&gt;
+ </BODY>
+ </HTML>
++ ====== h_config_maildir_location ======
++ <HTML>
++ <HEAD>
++ <TITLE>OPTION: <!--#echo var="VAR_maildir-location"--></TITLE>
++ </HEAD>
++ <BODY>
++ <H1>OPTION: <!--#echo var="VAR_maildir-location"--></H1>
++
++ <P>
++ This option should be used only if you have a Maildir folder which you
++ want to use as your INBOX. If this is not your case (or don't know what
++ this is), you can safely ignore this option.
++
++ <P>
++ This option overrides the default directory Pine uses to find the location of
++ your INBOX, in case this is in Maildir format. The default value of this
++ option is "Maildir", but in some systems, this directory could have been
++ renamed (e.g. to ".maildir"). If this is your case use this option to change
++ the default.
++
++ <P>
++ The value of this option is prefixed with the "~/" string to determine the
++ full path to your INBOX.
++
++ <P>
++ You should probably <A HREF="h_config_maildir">read</A> a few tips that
++ teach you how to configure your maildir for optimal performance. This
++ version also has <A HREF="h_config_courier_list">support</A> for the
++ Courier style file system when a maildir collection is accessed locally.
++
++ <P><UL>
++ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
++ </UL>
++ <P>
++ &lt;End of help on this topic&gt;
++ </BODY>
++ </HTML>
++ ====== h_config_maildir =====
++ <HTML>
++ <HEAD>
++ <TITLE>Maildir Support</TITLE>
++ </HEAD>
++ <BODY>
++ <H1>Maildir Support</H1>
++
++ This version of Alpine has been enhanced with Maildir support. This text is
++ intended to be a reference on its support.
++ <P>
++
++ A Maildir folder is a directory that contains three directories called
++ cur, tmp and new. A program that delivers mail (e.g. postfix) will put new
++ mail in the new directory. A program that reads mail will look for for old
++ messages in the cur directory, while it will look for new mail in the new
++ directory.
++ <P>
++
++ In order to use maildir support it is better to set your inbox-path to the
++ value &quot;#md/inbox&quot; (without quotes). This assumes that your mail
++ delivery agent is delivering new mail to ~/Maildir/new. If the directory
++ where new mail is being delivered is not called "Maildir", you can set the
++ name of the subdirectory of home where it is being delivered in the <A
++ HREF="h_config_maildir_location"><!--#echo var="VAR_maildir-location"--></A> configuration
++ variable. Most of the time you will not have to worry about the
++ <!--#echo var="VAR_maildirlocation"--> variable, because it will probably be set by your
++ administrator in the pine.conf configuration file.
++ <P>
++
++ One of the advantages of the Maildir support of this version of Alpine is
++ that you do not have to stop using folders in another styles (mbox, mbx,
++ etc.). This is desirable since the usage of a specific mail storage system
++ is a personal decision. Folders in the maildir format that are part of the
++ Mail collection will be recognized without any extra configuration of your
++ part. If your mail/ collection is located under the mail/ directory, then
++ creating a new maildir folder in this collection is done by pressing "A"
++ and entering the string "#driver.md/mail/newfolder". Observe that adding a
++ new folder as "newfolder" may not create such folder in maildir format.
++
++ <P>
++ If you would like to have all folders created in the maildir format by
++ default, you do so by adding a Maildir Collection. In order to convert
++ your current mail/ collection into a maildir collection, edit the
++ collection and change the path variable from &quot;mail/&quot; to
++ &quot;#md/mail&quot;. In a maildir collection folders of any other format
++ are ignored.
++
++ <P> Finally, This version also has
++ <A HREF="h_config_courier_list">support</A> for the Courier style file system
++ when a maildir collection is accessed locally.
++
++ <P>
++ <UL>
++ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
++ </UL><P>
++ &lt;End of help on this topic&gt;
++ </BODY>
++ </HTML>
+ ====== h_config_literal_sig =====
+ <HTML>
+ <HEAD>
+***************
+*** 29126,29131 ****
+--- 29222,29270 ----
+ <P>
+ &lt;End of help on this topic&gt;
+ </BODY>
++ </HTML>
++ ====== h_config_courier_list =====
++ <HTML>
++ <HEAD>
++ <TITLE>FEATURE: <!--#echo var="FEAT_courier-folder-list"--></TITLE>
++ </HEAD>
++ <BODY>
++ <H1>FEATURE: <!--#echo var="FEAT_courier-folder-list"--></H1>
++
++ In a maildir collection, a folder could be used as a directory to store
++ folders. In the Courier server if you create a folder, then a directory
++ with the same name is created. If you use this patch to access a
++ collection created by the Courier server, then the display of such
++ collection will look confusing. The best way to access a maildir
++ collection created by the Courier server is by using the &quot;#mc/&quot;
++ prefix instead of the &quot;#md/&quot; prefix. If you use this alternate
++ prefix, then this feature applies to you, otherwise you can safely ignore
++ the text that follows.
++ <P>
++ Depending on if you have enabled the option
++ <a href="h_config_separate_fold_dir_view"><!--#echo var="FEAT_separate-folder-and-directory-entries"--></a>
++ a folder may be listed as &quot;folder[.]&quot;, or as two entries in the
++ list by &quot;folder&quot; and &quot;folder.&quot;.
++ <P>
++ If this option is disabled, Pine will list local folders that are in Courier
++ style format, as &quot;folder&quot;, and those that are also directories as
++ &quot;folder[.]&quot;. This makes the default display cleaner.
++ <P>
++ If this feature is enabled then creating folders in a maildir collection
++ will create a directory with the same name. If this feature is disabled, then
++ a folder is considered a directory only if it contains subfolders, so you can
++ not create a directory with the same name as an exisiting folder unless
++ you create a subfolder of that folder first (e.g. if you have a folder
++ called &quot;foo&quot; simply add &quot;foo.bar&quot; directly. This will
++ create the directory &quot;foo&quot; and the subfolder &quot;bar&quot; of it).
++ <P>
++ Observe that this feature works only for maildir collections that are accessed
++ locally. If a collection is accessed remotely then this feature has no value,
++ as the report is created in a server, and Pine only reports what received
++ from the server in this case.
++ <P>
++ &lt;End of help on this topic&gt;
++ </BODY>
+ </HTML>
+ ====== h_config_verbose_post =====
+ <HTML>
+diff -rc alpine-2.00/pith/send.c alpine-2.00.maildir/pith/send.c
+*** alpine-2.00/pith/send.c 2008-08-06 13:25:58.000000000 -0500
+--- alpine-2.00.maildir/pith/send.c 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 256,261 ****
+--- 256,268 ----
+
+ if(exists & FEX_ISFILE){
+ context_apply(tmp, p_cntxt, mbox, sizeof(tmp));
++ #ifndef _WINDOWS
++ if (!struncmp(tmp, "#md/",4) || !struncmp(tmp, "#mc/", 4)){
++ char tmp2[MAILTMPLEN];
++ maildir_file_path(tmp, tmp2);
++ strcpy(tmp, tmp2);
++ }
++ #endif
+ if(!(IS_REMOTE(tmp) || is_absolute_path(tmp))){
+ /*
+ * The mbox is relative to the home directory.
+diff -rc alpine-2.00/README.maildir alpine-2.00.maildir/README.maildir
+*** alpine-2.00/README.maildir 2011-01-24 19:38:50.000000000 -0600
+--- alpine-2.00.maildir/README.maildir 2011-01-15 19:11:07.000000000 -0600
+***************
+*** 0 ****
+--- 1,153 ----
++ ---------------------------------------
++
++ Maildir Driver for Alpine 1.0
++ By Eduardo Chappa <chappa@washington.edu>
++ http://staff.washington.edu/chappa/alpine/
++
++ ---------------------------------------
++ 1. General Information About This Patch
++ ---------------------------------------
++
++ This patch adds support for the maildir format to Alpine. We take the
++ approach that this patch is one more driver among the number of formats
++ supported by Alpine (more generally c-client). This approach differs from
++ older versions of similar patches, in that once a maildir patch was
++ applied, it was assumed that all your folders would be created in the
++ maildir format.
++
++ This patch does not assume that maildir is a preferred format, instead
++ puts maildir in equal footing with other formats (mbox, mbx, mix, etc),
++ and so a maildir folder in the mail/ collection is treated in the same way
++ as any other folder in any other format. In other words, just by reading
++ the name of a folder, or opening it, or doing any operation with it, you
++ can not know in which format the folder is.
++
++ This implies that if you want to add a folder in the maildir format to the
++ mail/ collection, then you must add by pressing "A" in the folder list
++ collection and enter "#driver.md/mail/name_maildir_folder".
++
++ If you only want to use maildir, however, you can do so too. In this case,
++ you must create a maildir collection. In that collection, only maildir
++ folders will be listed. If there is any folder in any other format, that
++ folder will be ignored. In another words, any folder listed there is in
++ maildir format and can be accessed through that collection, conversely,
++ any folder not listed there is not in maildir format and there is no way
++ to access it using this collection.
++
++ In order to create a maildir collection, you could press M S L, and "A" to
++ add a collection. Fill in the required fields as follows:
++
++ Nickname : Anything
++ Server :
++ Path : #md/relative/path/to/maildir/collection/
++ View :
++
++ For example, if "path" is set to "#md/mail/", then Alpine will look for your
++ maildir folders that are in ~/mail/.
++
++ The code in this patch is mostly based in code for the unix driver plus
++ some combinations of the mh, mbx and nntp drivers for the c-client
++ library. Those drivers were designed by Mark Crispin, and bugs in this
++ code are not his bugs, but my own.
++
++ I got all the specification for this patch from
++ http://cr.yp.to/proto/maildir.html. If you know of a place with a better
++ specification for maildir format please let me know. The method this patch
++ uses to create a unique filename for a message is one of the "old
++ fashioned" methods. I realize that this is old fashioned, but it is
++ portable, and portability is the main reason why I decided to use an old
++ fashioned method (most methods are not portable. See the word
++ "Unfortunately" in that document).
++
++ --------------
++ 2. Other Goals
++ --------------
++
++ It is intended that this code will work well with any application
++ written using the c-client library. Of paramount importance is to make the
++ associated imap server work well when the server accesses a folder in
++ Maildir format. The program mailutil should also work flawlessly with this
++ implemetation of the driver.
++
++ It is intended that this driver be fast and stable. We intend not to
++ patch Alpine to make this driver do its work, unless such patching is for
++ fixing bugs in Alpine or to pass parameters to the driver.
++
++ ------------------------------------------------------------------------
++ 3. What are the known bugs of this implementation of the Maildir driver?
++ ------------------------------------------------------------------------
++
++ I don't know any at this time. There have been bugs before, though, but
++ I try to fix bugs as soon as they are reported. A complete list of updates
++ for this patch, which includes bug fixes, improvements and addition of new
++ features can be found at
++
++ http://staff.washington.edu/chappa/alpine/updates/maildir.html
++
++ ----------
++ 4. On UIDs
++ ----------
++
++ This patch keeps uids in the name of the file that contains the message,
++ by adding a ",u=" string to the file name to save the uid of a message. A
++ file is kept between sessions to save information on the last uid assigned
++ and its time of validity. Only one session with writing access can write
++ uids, all others must wait for the other session to assign them. The
++ session assigning uids creates a ".uidtemp" file which other sessions must
++ not disturb.
++
++ Uid support appeared in Alpine 1.00 (snapshot 925), and is experimental,
++ please report any problems.
++
++ --------------------------------------------
++ 5. Configuring Alpine and Setting up a Maildir
++ --------------------------------------------
++
++ Once this approach was chosen, it implied the following:
++
++ * This patch assumes that your INBOX is located at "$HOME/Maildir".
++ This is a directory which should have three subdirectories "cur",
++ "tmp" and "new". Mail is delivered to 'new' and read from 'cur'. I
++ have added a configuration option "maildir-location" which can be
++ used to tell Alpine where your Maildir inbox is, in case your system
++ do not use the above directory (e.g. your system may use
++ "~/.maildir"). In this case define that variable to be the name of
++ the directory where your e-mail is being delivered (e.g.
++ ".maildir").
++
++ * If you want to use the above configuration as your inbox, you must
++ define your inbox-path as "#md/inbox" (no quotes). You can define
++ the inbox-path like above even if you have changed the
++ maildir-location variable. That's the whole point of that variable.
++
++ -----------------------------------
++ 6. What about Courier file systems?
++ -----------------------------------
++
++ In a courier file system all folders are subfolders of a root folder
++ called INBOX. Normally INBOX is located at ~/Maildir and subfolders are
++ "dot" directories in ~/Maildir. For example ~/Maildir/.Trash is a
++ subfolder of INBOX and is accessed with the nickname "INBOX.Trash".
++
++ You can not access folders in this way unless you preceed them with the
++ string "#mc/". The purpose of the string "#mc/" is to warn Alpine that a
++ collection in the Courier format is going to be accessed, so you can
++ SELECT a folder like "#mc/INBOX.Trash", but not "INBOX.Trash"
++
++ You can access a collection through a server, but if you want to access a
++ collection of folders created using the Courier server, you MUST edit your
++ ".pinerc" file and enter the definition of the collection as follows:
++
++ folder-collections="Anything you want" #mc/INBOX.[]
++
++ You can replace the string "#mc/INBOX." by something different, for example
++ "#mc/Courier/." will make Alpine search for your collection in ~/Courier.
++
++ You can not add this directly into Alpine because Alpine fails to accept this
++ value from its input, but it takes it correctly when it is added through
++ the ".pinerc" file.
++
++ You can access your inbox as "#mc/INBOX" or "#md/INBOX". Both definitions
++ point to the same place.
++
++ Last Updated February 9, 2008