Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
0010991c
...
0010991cc712eb88cdbbe22d9c4021f74a72e4cd
authored
2004-01-08 16:27:24 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Implemented
1 parent
985fa48d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
527 additions
and
112 deletions
mailbox/maildir/mbox.c
mailbox/maildir/mbox.c
View file @
0010991
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2002, 2003,
2004 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -15,24 +16,25 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* First draft by
Jeff Bailey based on mbox by Alain Magloire
*/
/* First draft by
Sergey Poznyakoff
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef ENABLE_MAILDIR
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
#include <dirent.h>
#ifdef WITH_PTHREAD
# ifdef HAVE_PTHREAD_H
...
...
@@ -41,184 +43,597 @@
# endif
#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include <string.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <mailbox0.h>
#include <registrar0.h>
#include <mailutils/address.h>
#include <mailutils/attribute.h>
#include <mailutils/body.h>
#include <mailutils/debug.h>
#include <mailutils/envelope.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/header.h>
#include <mailutils/locker.h>
#include <mailutils/message.h>
#include <mailutils/mutil.h>
#include <mailutils/observer.h>
#include <mailutils/property.h>
#include <mailutils/stream.h>
#include <mailutils/url.h>
#include <mailutils/observer.h>
#include <mailutils/errno.h>
#include <mailbox0.h>
#include <registrar0.h>
#include <amd.h>
/* Mailbox concrete implementation. */
static
int
maildir_open
__P
((
mailbox_t
,
int
));
static
int
maildir_close
__P
((
mailbox_t
));
static
void
maildir_destroy
__P
((
mailbox_t
));
static
int
maildir_get_message
__P
((
mailbox_t
,
size_t
,
message_t
*
));
/* static int maildir_get_message_by_uid __P ((mailbox_t, size_t, message_t *)); */
static
int
maildir_append_message
__P
((
mailbox_t
,
message_t
));
static
int
maildir_messages_count
__P
((
mailbox_t
,
size_t
*
));
static
int
maildir_messages_recent
__P
((
mailbox_t
,
size_t
*
));
static
int
maildir_message_unseen
__P
((
mailbox_t
,
size_t
*
));
static
int
maildir_expunge
__P
((
mailbox_t
));
static
int
maildir_save_attributes
__P
((
mailbox_t
));
static
int
maildir_uidvalidity
__P
((
mailbox_t
,
unsigned
long
*
));
static
int
maildir_uidnext
__P
((
mailbox_t
,
size_t
*
));
static
int
maildir_scan
__P
((
mailbox_t
,
size_t
,
size_t
*
));
static
int
maildir_is_updated
__P
((
mailbox_t
));
static
int
maildir_get_size
__P
((
mailbox_t
,
off_t
*
));
struct
_maildir_message
{
struct
_amd_message
amd_message
;
int
newflag
;
char
*
file_name
;
};
/* Attribute handling.
FIXME: P (Passed), D (Draft) and F (Flagged) are not handled */
static
struct
info_map
{
char
letter
;
int
flag
;
}
info_map
[]
=
{
{
'R'
,
MU_ATTRIBUTE_READ
},
{
'S'
,
MU_ATTRIBUTE_SEEN
},
{
'T'
,
MU_ATTRIBUTE_DELETED
},
{
0
},
};
#define info_map_size (sizeof (info_map) / sizeof (info_map[0]))
int
_mailbox_maildir_init
(
mailbox_t
mailbox
)
static
int
info_map_letter
(
int
c
)
{
struct
info_map
*
p
;
if
(
mailbox
==
NULL
)
return
EINVAL
;
for
(
p
=
info_map
;
p
<
info_map
+
info_map_size
;
p
++
)
if
(
p
->
letter
==
c
)
return
p
->
flag
;
return
0
;
}
/* Overloading the defaults. */
mailbox
->
_destroy
=
maildir_destroy
;
/* NOTE: BUF must be at least 7 bytes long */
static
int
flags_to_info
(
int
flags
,
char
*
buf
)
{
struct
info_map
*
p
;
for
(
p
=
info_map
;
p
<
info_map
+
info_map_size
;
p
++
)
if
(
p
->
flag
&
flags
)
*
buf
++
=
p
->
letter
;
*
buf
=
0
;
return
0
;
}
mailbox
->
_open
=
maildir_open
;
mailbox
->
_close
=
maildir_close
;
static
int
info_to_flags
(
char
*
buf
)
{
int
flags
=
0
;
struct
info_map
*
p
;
/* Overloading of the entire mailbox object methods. */
mailbox
->
_get_message
=
maildir_get_message
;
mailbox
->
_append_message
=
maildir_append_message
;
mailbox
->
_messages_count
=
maildir_messages_count
;
mailbox
->
_messages_recent
=
maildir_messages_recent
;
mailbox
->
_message_unseen
=
maildir_message_unseen
;
mailbox
->
_expunge
=
maildir_expunge
;
mailbox
->
_save_attributes
=
maildir_save_attributes
;
mailbox
->
_uidvalidity
=
maildir_uidvalidity
;
mailbox
->
_uidnext
=
maildir_uidnext
;
for
(
p
=
info_map
;
p
<
info_map
+
info_map_size
;
p
++
)
if
(
strchr
(
buf
,
p
->
letter
))
flags
|=
p
->
flag
;
return
0
;
}
mailbox
->
_scan
=
maildir_scan
;
mailbox
->
_is_updated
=
maildir_is_updated
;
static
int
maildir_message_cmp
(
struct
_amd_message
*
a
,
struct
_amd_message
*
b
)
{
unsigned
long
na
=
strtoul
(((
struct
_maildir_message
*
)
a
)
->
file_name
,
NULL
,
10
);
unsigned
long
nb
=
strtoul
(((
struct
_maildir_message
*
)
b
)
->
file_name
,
NULL
,
10
);
if
(
na
>
nb
)
return
1
;
if
(
na
<
nb
)
return
-
1
;
return
0
;
}
mailbox
->
_get_size
=
maildir_get_size
;
void
msg_free
(
struct
_amd_message
*
amsg
)
{
struct
_maildir_message
*
mp
=
(
struct
_maildir_message
*
)
amsg
;
free
(
mp
->
file_name
);
}
return
0
;
/* okdoke */
char
*
maildir_gethostname
()
{
char
hostname
[
256
];
char
*
hp
;
char
*
p
;
size_t
s
;
if
(
gethostname
(
hostname
,
sizeof
hostname
)
<
0
)
strcpy
(
hostname
,
"localhost"
);
for
(
s
=
0
,
p
=
hostname
;
*
p
;
p
++
)
if
(
*
p
==
'/'
||
*
p
==
':'
)
s
+=
4
;
if
(
s
)
{
char
*
q
;
hp
=
malloc
(
strlen
(
hostname
))
+
s
+
1
;
for
(
p
=
hostname
,
q
=
hp
;
*
p
;
p
++
)
switch
(
*
p
)
{
case
'/'
:
memcpy
(
q
,
"
\\
057"
,
4
);
q
+=
4
;
break
;
case
':'
:
memcpy
(
q
,
"
\\
072"
,
4
);
q
+=
4
;
break
;
default:
*
q
++
=
*
p
++
;
}
*
q
=
0
;
}
else
hp
=
strdup
(
hostname
);
return
hp
;
}
/* Destruct maildir setup */
static
void
maildir_destroy
(
mailbox_t
mailbox
)
int
read_random
(
void
*
buf
,
size_t
size
)
{
return
;
int
rc
;
int
fd
=
open
(
"/dev/urandom"
,
O_RDONLY
);
if
(
fd
==
-
1
)
return
-
1
;
rc
=
read
(
fd
,
buf
,
size
);
close
(
fd
);
return
rc
!=
size
;
}
/* Open the file. For MU_STREAM_READ, the code tries mmap() first and fall
back to normal file. */
static
int
maildir_open
(
mailbox_t
mailbox
,
int
flags
)
#define PERMS 0700
#define TMPSUF "tmp"
#define CURSUF "cur"
#define NEWSUF "new"
static
char
*
mkfilename
(
char
*
directory
,
char
*
suffix
,
char
*
name
)
{
return
-
1
;
size_t
size
=
strlen
(
directory
)
+
1
+
strlen
(
suffix
)
+
1
;
char
*
tmp
;
if
(
name
)
size
+=
1
+
strlen
(
name
);
tmp
=
malloc
(
size
);
sprintf
(
tmp
,
"%s/%s"
,
directory
,
suffix
);
if
(
name
)
{
strcat
(
tmp
,
"/"
);
strcat
(
tmp
,
name
);
}
return
tmp
;
}
static
int
m
aildir_close
(
mailbox_t
mailbox
)
static
char
*
m
k_info_filename
(
char
*
directory
,
char
*
suffix
,
char
*
name
,
int
flags
)
{
return
-
1
;
char
fbuf
[
9
];
char
*
tmp
;
int
namelen
;
size_t
size
;
tmp
=
strchr
(
name
,
':'
);
if
(
!
tmp
)
namelen
=
strlen
(
name
);
else
namelen
=
tmp
-
name
;
size
=
strlen
(
directory
)
+
1
+
strlen
(
suffix
)
+
1
+
namelen
+
1
;
flags_to_info
(
flags
,
fbuf
);
size
+=
3
+
strlen
(
fbuf
);
tmp
=
malloc
(
size
);
if
(
fbuf
[
0
])
sprintf
(
tmp
,
"%s/%s/%*.*s:2"
,
directory
,
suffix
,
namelen
,
namelen
,
name
);
else
sprintf
(
tmp
,
"%s/%s/%*.*s:2,%s"
,
directory
,
suffix
,
namelen
,
namelen
,
name
,
fbuf
);
return
tmp
;
}
/* Cover function that call the real thing, maildir_scan(), with
notification set. */
static
int
maildir_scan
(
mailbox_t
mailbox
,
size_t
msgno
,
size_t
*
pcount
)
char
*
maildir_uniq
(
struct
_amd_data
*
amd
,
int
fd
)
{
return
0
;
char
buffer
[
PATH_MAX
];
int
ind
=
0
;
#define FMT(fmt,val) do {\
ind += snprintf(buffer+ind, sizeof buffer-ind, fmt, val); \
} while (0)
#define PFX(pfx,fmt,val) do {\
if (ind < sizeof buffer-1) {\
buffer[ind++] = pfx;\
FMT(fmt,val);\
}\
} while (0)
#define COPY(s) do {\
char *p; \
for (p = s; ind < sizeof buffer-1 && *p;) \
buffer[ind++] = *p++;\
} while (0);
char
*
hostname
=
maildir_gethostname
();
struct
timeval
tv
;
unsigned
long
n
;
struct
stat
st
;
gettimeofday
(
&
tv
,
NULL
);
FMT
(
"%lu"
,
tv
.
tv_sec
);
COPY
(
"."
);
if
(
read_random
(
&
n
,
32
))
PFX
(
'R'
,
"%lX"
,
n
);
if
(
fd
>
0
&&
fstat
(
fd
,
&
st
)
==
0
)
{
PFX
(
'I'
,
"%lX"
,
(
unsigned
long
)
st
.
st_ino
);
PFX
(
'V'
,
"%lX"
,
(
unsigned
long
)
st
.
st_dev
);
}
PFX
(
'M'
,
"%lu"
,
tv
.
tv_usec
);
PFX
(
'P'
,
"%lu"
,
(
unsigned
long
)
getpid
());
PFX
(
'Q'
,
"%lu"
,
(
unsigned
long
)
amd
->
msg_count
);
PFX
(
'.'
,
"%s"
,
hostname
);
free
(
hostname
);
buffer
[
ind
]
=
0
;
return
strdup
(
buffer
);
}
/* FIXME: How to handle a shrink ? meaning, the &^$^@%#@^& user start two
browsers and deleted emails in one session. My views is that we should
scream bloody murder and hunt them with a machette. But for now just play
dumb, but maybe the best approach is to pack our things and leave
.i.e exit()/abort(). */
static
int
maildir_is_updated
(
mailbox_t
mailbox
)
char
*
maildir_message_name
(
struct
_amd_message
*
amsg
,
int
deleted
)
{
return
-
1
;
struct
_maildir_message
*
msg
=
(
struct
_maildir_message
*
)
amsg
;
return
mkfilename
(
amsg
->
amd
->
name
,
msg
->
newflag
?
NEWSUF
:
CURSUF
,
msg
->
file_name
);
}
static
int
maildir_
expunge
(
mailbox_t
mailbox
)
static
void
maildir_
msg_free
(
struct
_amd_message
*
amsg
)
{
return
-
1
;
struct
_maildir_message
*
mp
=
(
struct
_maildir_message
*
)
amsg
;
free
(
mp
->
file_name
);
}
static
int
maildir_get_size
(
mailbox_t
mailbox
,
off_t
*
psize
)
/* According to http://www.qmail.org/qmail-manual-html/man5/maildir.html
a file in tmp may be safely removed if it has not been accessed in 36
hours */
static
void
maildir_delete_file
(
char
*
dirname
,
char
*
filename
)
{
return
-
1
;
struct
stat
st
;
char
*
name
=
mkfilename
(
dirname
,
filename
,
NULL
);
if
(
stat
(
name
,
&
st
)
==
0
)
{
if
(
time
(
NULL
)
-
st
.
st_atime
>
36
*
3600
)
remove
(
name
);
}
free
(
name
);
}
static
int
maildir_save_attributes
(
mailbox_t
mailbox
)
int
maildir_opendir
(
DIR
**
dir
,
char
*
name
,
int
permissions
)
{
return
-
1
;
*
dir
=
opendir
(
name
);
if
(
!*
dir
)
{
if
(
errno
==
ENOENT
)
{
if
(
mkdir
(
name
,
permissions
))
return
errno
;
*
dir
=
opendir
(
name
);
if
(
!*
dir
)
return
errno
;
}
else
return
errno
;
}
return
0
;
}
#define NTRIES 30
/* Delivery to "dir/new" */
static
int
maildir_
get_message
(
mailbox_t
mailbox
,
size_t
msgno
,
message_t
*
pmsg
)
maildir_
msg_init
(
struct
_amd_data
*
amd
,
struct
_amd_message
*
amm
)
{
return
-
1
;
struct
_maildir_message
*
msg
=
(
struct
_maildir_message
*
)
amm
;
char
*
name
;
struct
stat
st
;
int
i
;
/* chdir (amd->name); FIXME */
name
=
maildir_uniq
(
amd
,
-
1
);
for
(
i
=
0
;
i
<
NTRIES
;
i
++
)
{
if
(
stat
(
name
,
&
st
)
<
0
&&
errno
==
ENOENT
)
{
msg
->
file_name
=
name
;
return
0
;
}
sleep
(
2
);
}
free
(
name
);
return
MU_ERR_BAD_RESUMPTION
;
}
static
int
maildir_
append_message
(
mailbox_t
mailbox
,
message_t
msg
)
maildir_
msg_finish_delivery
(
struct
_amd_data
*
amd
,
struct
_amd_message
*
amm
)
{
return
-
1
;
struct
_maildir_message
*
msg
=
(
struct
_maildir_message
*
)
amm
;
char
*
oldname
=
mkfilename
(
amd
->
name
,
TMPSUF
,
msg
->
file_name
);
char
*
newname
=
mkfilename
(
amd
->
name
,
NEWSUF
,
msg
->
file_name
);
unlink
(
newname
);
if
(
link
(
oldname
,
newname
))
{
unlink
(
oldname
);
msg
->
newflag
=
1
;
}
free
(
oldname
);
free
(
newname
);
return
0
;
}
static
int
maildir_messages_count
(
mailbox_t
mailbox
,
size_t
*
pcount
)
/* Maldir scanning */
int
maildir_flush
(
struct
_amd_data
*
amd
)
{
return
-
1
;
int
rc
;
DIR
*
dir
;
struct
dirent
*
entry
;
char
*
tmpname
=
malloc
(
strlen
(
amd
->
name
)
+
sizeof
TMPSUF
);
strcpy
(
tmpname
,
amd
->
name
);
strcat
(
tmpname
,
TMPSUF
);
rc
=
maildir_opendir
(
&
dir
,
tmpname
,
PERMS
);
if
(
rc
)
{
free
(
tmpname
);
return
rc
;
}
while
((
entry
=
readdir
(
dir
)))
{
switch
(
entry
->
d_name
[
0
])
{
case
'.'
:
break
;
default
:
maildir_delete_file
(
tmpname
,
entry
->
d_name
);
break
;
}
}
free
(
tmpname
);
closedir
(
dir
);
return
0
;
}
/* A "recent" message is the one not marked with MU_ATTRIBUTE_SEEN
('O' in the Status header), i.e. a message that is first seen
by the current session (see attributes.h) */
static
int
maildir_messages_recent
(
mailbox_t
mailbox
,
size_t
*
pcount
)
int
maildir_deliver_new
(
struct
_amd_data
*
amd
,
DIR
*
dir
)
{
return
-
1
;
struct
dirent
*
entry
;
while
((
entry
=
readdir
(
dir
)))
{
char
*
oldname
,
*
newname
;
switch
(
entry
->
d_name
[
0
])
{
case
'.'
:
break
;
default
:
oldname
=
mkfilename
(
amd
->
name
,
NEWSUF
,
entry
->
d_name
);
newname
=
mk_info_filename
(
amd
->
name
,
CURSUF
,
entry
->
d_name
,
0
);
rename
(
oldname
,
newname
);
free
(
oldname
);
free
(
newname
);
}
}
return
0
;
}
/* An "unseen" message is the one that has not been read yet */
static
int
maildir_message_unseen
(
mailbox_t
mailbox
,
size_t
*
pmsgno
)
static
struct
_maildir_message
*
maildir_message_lookup
(
struct
_amd_data
*
amd
,
char
*
file_name
)
{
return
-
1
;
struct
_maildir_message
*
msg
;
char
*
p
=
strchr
(
file_name
,
':'
);
size_t
length
=
p
?
p
-
file_name
:
strlen
(
file_name
);
int
rc
;
for
(
msg
=
(
struct
_maildir_message
*
)
amd
->
msg_head
;
msg
&&
strlen
(
msg
->
file_name
)
>=
length
&&
(
rc
=
memcmp
(
msg
->
file_name
,
file_name
,
length
))
<
0
;
msg
=
(
struct
_maildir_message
*
)
msg
->
amd_message
.
next
)
;
return
rc
==
0
?
msg
:
NULL
;
}
static
int
maildir_
uidvalidity
(
mailbox_t
mailbox
,
unsigned
long
*
puidvalidity
)
maildir_
scan_dir
(
struct
_amd_data
*
amd
,
DIR
*
dir
)
{
return
-
1
;
struct
_maildir_message
*
msg
;
struct
dirent
*
entry
;
while
((
entry
=
readdir
(
dir
)))
{
char
*
p
;
int
insert
;
switch
(
entry
->
d_name
[
0
])
{
case
'.'
:
break
;
default
:
msg
=
maildir_message_lookup
(
amd
,
entry
->
d_name
);
if
(
msg
)
{
free
(
msg
->
file_name
);
msg
->
newflag
=
0
;
insert
=
0
;
}
else
{
msg
=
calloc
(
1
,
sizeof
(
*
msg
));
insert
=
1
;
}
msg
->
file_name
=
strdup
(
entry
->
d_name
);
p
=
strchr
(
msg
->
file_name
,
':'
);
if
(
p
&&
strcmp
(
p
+
1
,
"2,"
)
==
0
)
msg
->
amd_message
.
attr_flags
=
info_to_flags
(
p
+
3
);
else
msg
->
amd_message
.
attr_flags
=
0
;
msg
->
amd_message
.
deleted
=
msg
->
amd_message
.
attr_flags
&
MU_ATTRIBUTE_DELETED
;
if
(
insert
)
_amd_message_insert
(
amd
,
(
struct
_amd_message
*
)
msg
);
}
}
return
0
;
}
static
int
maildir_uidnext
(
mailbox_t
mailbox
,
size_t
*
puidnext
)
maildir_scan0
(
mailbox_t
mailbox
,
size_t
msgno
ARG_UNUSED
,
size_t
*
pcount
,
int
do_notify
)
{
return
-
1
;
struct
_amd_data
*
amd
=
mailbox
->
data
;
DIR
*
dir
;
int
status
=
0
;
char
*
name
;
struct
stat
st
;
if
(
amd
==
NULL
)
return
EINVAL
;
monitor_wrlock
(
mailbox
->
monitor
);
/* 1st phase: Flush tmp/ */
maildir_flush
(
amd
);
/* 2nd phase: Scan and deliver messages from new */
name
=
mkfilename
(
amd
->
name
,
NEWSUF
,
NULL
);
status
=
maildir_opendir
(
&
dir
,
name
,
PERMS
);
if
(
status
==
0
)
{
maildir_deliver_new
(
amd
,
dir
);
closedir
(
dir
);
}
free
(
name
);
name
=
mkfilename
(
amd
->
name
,
CURSUF
,
NULL
);
/* 3rd phase: Scan cur/ */
status
=
maildir_opendir
(
&
dir
,
name
,
PERMS
);
if
(
status
==
0
)
{
status
=
maildir_scan_dir
(
amd
,
dir
);
closedir
(
dir
);
}
free
(
name
);
if
(
do_notify
)
{
struct
_amd_message
*
mp
;
for
(
mp
=
amd
->
msg_head
;
mp
;
mp
=
mp
->
next
)
{
DISPATCH_ADD_MSG
(
mailbox
,
amd
);
}
}
if
(
stat
(
amd
->
name
,
&
st
)
==
0
)
amd
->
mtime
=
st
.
st_mtime
;
if
(
pcount
)
*
pcount
=
amd
->
msg_count
;
/* Reset the uidvalidity. */
if
(
amd
->
msg_count
>
0
)
{
if
(
amd
->
uidvalidity
==
0
)
{
amd
->
uidvalidity
=
(
unsigned
long
)
time
(
NULL
);
/* FIXME amd->uidnext = amd->msg_count + 1;*/
/* Tell that we have been modified for expunging. */
if
(
amd
->
msg_head
)
{
amd_message_stream_open
(
amd
->
msg_head
);
amd_message_stream_close
(
amd
->
msg_head
);
amd
->
msg_head
->
attr_flags
|=
MU_ATTRIBUTE_MODIFIED
;
}
}
}
/* Clean up the things */
amd_cleanup
(
mailbox
);
return
status
;
}
int
_mailbox_maildir_init
(
mailbox_t
mailbox
)
{
int
rc
;
struct
_amd_data
*
amd
;
rc
=
amd_init_mailbox
(
mailbox
,
sizeof
(
struct
_amd_data
),
&
amd
);
if
(
rc
)
return
rc
;
amd
->
msg_size
=
sizeof
(
struct
_maildir_message
);
amd
->
msg_free
=
maildir_msg_free
;
amd
->
msg_init_delivery
=
maildir_msg_init
;
amd
->
msg_finish_delivery
=
maildir_msg_finish_delivery
;
amd
->
msg_file_name
=
maildir_message_name
;
amd
->
scan0
=
maildir_scan0
;
amd
->
msg_cmp
=
maildir_message_cmp
;
amd
->
message_uid
=
NULL
;
/* FIXME */
amd
->
next_uid
=
NULL
;
/* FIXME */
/* Set our properties. */
{
property_t
property
=
NULL
;
mailbox_get_property
(
mailbox
,
&
property
);
property_set_value
(
property
,
"TYPE"
,
"MAILDIR"
,
1
);
}
return
0
;
}
#endif
...
...
Please
register
or
sign in
to post a comment