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
b76ed30a
...
b76ed30a80500ab1af374ba5955355896bdafa2d
authored
2001-09-10 15:04:21 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Implemented append.
Do not read deleted messages when doing mailbox scan.
1 parent
931b3549
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
192 additions
and
124 deletions
mailbox/mbx_mh.c
mailbox/mbx_mh.c
View file @
b76ed30
...
...
@@ -65,7 +65,7 @@ struct _mh_message
off_t
body_start
;
/* Offset of body start in the message file */
off_t
body_end
;
/* Offset of body end (size of file, effectively */
size_t
seq_number
;
/* message sequence number */
size_t
seq_number
;
/* message sequence number */
size_t
uid
;
/* IMAP uid. */
int
attr_flags
;
/* Attribute flags */
...
...
@@ -213,7 +213,7 @@ _mailbox_mh_init (mailbox_t mailbox)
mailbox
->
_get_size
=
mh_get_size
;
/* Set our properties. */
mailbox
->
properties
=
calloc
(
1
,
sizeof
(
*
(
mailbox
->
properties
)
));
mailbox
->
properties
=
calloc
(
1
,
sizeof
(
*
mailbox
->
properties
));
if
(
mailbox
->
properties
==
NULL
)
return
ENOMEM
;
mailbox
->
properties_count
=
1
;
...
...
@@ -254,8 +254,6 @@ mh_destroy (mailbox_t mailbox)
static
int
mh_open
(
mailbox_t
mailbox
,
int
flags
)
{
/* unsigned long seq_num = 0; */
/* struct dirent *entry; */
struct
_mh_data
*
mhd
=
mailbox
->
data
;
int
status
=
0
;
struct
stat
st
;
...
...
@@ -311,27 +309,11 @@ _mh_get_message_seq (struct _mh_data *mhd, size_t seq)
}
static
int
mh_get_message
(
mailbox_t
mailbox
,
size_t
msgno
,
message_t
*
pmsg
)
_mh_attach_message
(
mailbox_t
mailbox
,
struct
_mh_message
*
mhm
,
message_t
*
pmsg
)
{
int
status
;
struct
_mh_data
*
mhd
=
mailbox
->
data
;
struct
_mh_message
*
mhm
;
message_t
msg
=
NULL
;
/* Sanity checks. */
if
(
pmsg
==
NULL
||
mhd
==
NULL
)
return
EINVAL
;
/* If we did not start a scanning yet do it now. */
if
(
mhd
->
msg_count
==
0
)
{
status
=
mh_scan0
(
mailbox
,
1
,
NULL
);
if
(
status
!=
0
)
return
status
;
}
if
((
mhm
=
_mh_get_message
(
mhd
,
msgno
))
==
NULL
)
return
EINVAL
;
message_t
msg
;
/* Check if we already have it. */
if
(
mhm
->
message
)
...
...
@@ -341,9 +323,6 @@ mh_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg)
return
0
;
}
MAILBOX_DEBUG2
(
mailbox
,
MU_DEBUG_TRACE
,
"mh_get_message(%s, %d)
\n
"
,
mhd
->
name
,
msgno
);
/* Get an empty message struct. */
status
=
message_create
(
&
msg
,
mhm
);
if
(
status
!=
0
)
...
...
@@ -426,18 +405,185 @@ mh_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg)
mhm
->
message
=
msg
;
message_set_mailbox
(
msg
,
mailbox
,
mhm
);
*
pmsg
=
msg
;
if
(
pmsg
)
*
pmsg
=
msg
;
return
0
;
}
static
int
mh_get_message
(
mailbox_t
mailbox
,
size_t
msgno
,
message_t
*
pmsg
)
{
int
status
;
struct
_mh_data
*
mhd
=
mailbox
->
data
;
struct
_mh_message
*
mhm
;
/* Sanity checks. */
if
(
pmsg
==
NULL
||
mhd
==
NULL
)
return
EINVAL
;
/* If we did not start a scanning yet do it now. */
if
(
mhd
->
msg_count
==
0
)
{
status
=
mh_scan0
(
mailbox
,
1
,
NULL
);
if
(
status
!=
0
)
return
status
;
}
if
((
mhm
=
_mh_get_message
(
mhd
,
msgno
))
==
NULL
)
return
EINVAL
;
return
_mh_attach_message
(
mailbox
,
mhm
,
pmsg
);
}
static
size_t
_mh_next_seq
(
struct
_mh_data
*
mhd
)
{
return
mhd
->
msg_tail
?
mhd
->
msg_tail
->
seq_number
:
1
;
}
static
FILE
*
_mh_tempfile
(
struct
_mh_data
*
mhd
,
char
**
namep
)
{
char
*
filename
;
int
fd
;
filename
=
malloc
(
strlen
(
mhd
->
name
)
+
/*'/'*/
1
+
/* "muXXXXXX" */
8
+
1
);
if
(
!
filename
)
return
NULL
;
sprintf
(
filename
,
"%s/muXXXXXX"
,
mhd
->
name
);
#ifdef HAVE_MKSTEMP
{
int
save_mask
=
umask
(
077
);
fd
=
mkstemp
(
filename
);
umask
(
save_mask
);
}
#else
if
(
mktemp
(
filename
))
fd
=
open
(
filename
,
O_CREAT
|
O_EXCL
|
O_RDWR
,
0600
);
else
fd
=
-
1
;
#endif
if
(
fd
==
-
1
)
{
free
(
filename
);
return
NULL
;
}
*
namep
=
filename
;
return
fdopen
(
fd
,
"w"
);
}
static
int
_mh_message_save
(
struct
_mh_data
*
mhd
,
struct
_mh_message
*
mhm
,
int
expunge
)
{
stream_t
stream
=
NULL
;
char
*
name
,
*
buf
,
*
msg_name
;
size_t
n
,
off
=
0
;
size_t
bsize
;
FILE
*
fp
;
message_t
msg
=
mhm
->
message
;
header_t
hdr
;
int
status
;
attribute_t
attr
;
body_t
body
;
fp
=
_mh_tempfile
(
mhm
->
mhd
,
&
name
);
if
(
!
fp
)
{
free
(
mhm
);
return
errno
;
}
message_size
(
msg
,
&
bsize
);
/* Try to allocate large buffer */
for
(;
bsize
>
1
;
bsize
/=
2
)
if
((
buf
=
malloc
(
bsize
)))
break
;
if
(
!
bsize
)
{
free
(
mhm
);
return
ENOMEM
;
}
/* Copy flags */
message_get_header
(
msg
,
&
hdr
);
header_get_stream
(
hdr
,
&
stream
);
off
=
0
;
while
((
status
=
stream_readline
(
stream
,
buf
,
bsize
,
off
,
&
n
))
==
0
&&
n
!=
0
)
{
if
(
buf
[
0
]
==
'\n'
)
break
;
if
(
!
(
strncasecmp
(
buf
,
"status:"
,
7
)
==
0
||
strncasecmp
(
buf
,
"x-imapbase:"
,
11
)
==
0
||
strncasecmp
(
buf
,
"x-iud:"
,
6
)
==
0
))
fprintf
(
fp
,
"%s"
,
buf
);
off
+=
n
;
}
/* Add imapbase */
if
(
!
mhd
->
msg_head
||
(
mhd
->
msg_head
==
mhm
))
/*FIXME*/
fprintf
(
fp
,
"X-IMAPbase: %lu %u
\n
"
,
mhd
->
uidvalidity
,
mhd
->
uidnext
);
/* Add status */
message_get_attribute
(
msg
,
&
attr
);
attribute_to_string
(
attr
,
buf
,
bsize
,
&
n
);
fprintf
(
fp
,
"%s"
,
buf
);
/* Add UID */
fprintf
(
fp
,
"X-UID: %d
\n
"
,
mhm
->
uid
);
fprintf
(
fp
,
"
\n
"
);
/* Copy message body */
message_get_body
(
msg
,
&
body
);
body_get_stream
(
body
,
&
stream
);
off
=
0
;
while
(
stream_read
(
stream
,
buf
,
bsize
,
off
,
&
n
)
==
0
&&
n
!=
0
)
{
fwrite
(
buf
,
1
,
n
,
fp
);
off
+=
n
;
}
free
(
buf
);
fclose
(
fp
);
msg_name
=
_mh_message_name
(
mhm
,
mhm
->
deleted
);
rename
(
name
,
msg_name
);
free
(
name
);
free
(
msg_name
);
return
0
;
}
static
int
mh_append_message
(
mailbox_t
mailbox
,
message_t
msg
)
{
/*FIXME*/
(
void
)
mailbox
;
(
void
)
msg
;
return
ENOSYS
;
int
status
;
struct
_mh_data
*
mhd
=
mailbox
->
data
;
struct
_mh_message
*
mhm
;
if
(
!
mailbox
||
!
msg
)
return
EINVAL
;
mhm
=
calloc
(
1
,
sizeof
(
*
mhm
));
if
(
!
mhm
)
return
ENOMEM
;
mhm
->
seq_number
=
_mh_next_seq
(
mhd
);
mhm
->
uid
=
mhd
->
uidnext
++
;
mhm
->
message
=
msg
;
status
=
_mh_message_save
(
mhd
,
mhm
,
0
);
mhm
->
message
=
NULL
;
/* Insert and re-scan the message */
_mh_message_insert
(
mhd
,
mhm
);
mh_message_stream_open
(
mhm
);
mh_message_stream_close
(
mhm
);
return
status
;
}
static
int
...
...
@@ -511,82 +657,6 @@ mh_message_unseen (mailbox_t mailbox, size_t *pmsgno)
return
0
;
}
static
FILE
*
_mh_tempfile
(
struct
_mh_data
*
mhd
,
char
**
namep
)
{
char
*
filename
;
int
fd
;
filename
=
malloc
(
strlen
(
mhd
->
name
)
+
/*'/'*/
1
+
/* "muXXXXXX" */
8
+
1
);
if
(
!
filename
)
return
NULL
;
sprintf
(
filename
,
"%s/muXXXXXX"
,
mhd
->
name
);
#ifdef HAVE_MKSTEMP
{
int
save_mask
=
umask
(
077
);
fd
=
mkstemp
(
filename
);
umask
(
save_mask
);
}
#else
if
(
mktemp
(
filename
))
fd
=
open
(
filename
,
O_CREAT
|
O_EXCL
|
O_RDWR
,
0600
);
else
fd
=
-
1
;
#endif
if
(
fd
==
-
1
)
{
free
(
filename
);
return
NULL
;
}
*
namep
=
filename
;
return
fdopen
(
fd
,
"w"
);
}
/* Save message. FIXME: This is very raw. */
static
int
_mh_message_save
(
struct
_mh_message
*
mhm
,
char
*
msg_name
)
{
stream_t
stream
=
NULL
;
FILE
*
fp
;
char
buffer
[
512
];
off_t
off
=
0
;
size_t
n
;
char
*
filename
;
fp
=
_mh_tempfile
(
mhm
->
mhd
,
&
filename
);
if
(
!
fp
)
return
errno
;
if
(
!
mhm
->
message
)
{
mh_pool_open
(
mhm
);
stream
=
mhm
->
stream
;
}
else
message_get_stream
(
mhm
->
message
,
&
stream
);
if
(
!
stream
)
{
fclose
(
fp
);
return
errno
;
}
while
(
stream_readline
(
stream
,
buffer
,
sizeof
(
buffer
)
-
1
,
off
,
&
n
)
==
0
&&
n
!=
0
)
{
fwrite
(
buffer
,
1
,
n
,
fp
);
off
+=
n
;
}
fclose
(
fp
);
rename
(
filename
,
msg_name
);
free
(
filename
);
return
0
;
}
static
int
mh_expunge
(
mailbox_t
mailbox
)
{
...
...
@@ -614,30 +684,26 @@ mh_expunge (mailbox_t mailbox)
while
(
mhm
)
{
struct
_mh_message
*
next
=
mhm
->
next
;
char
*
msg_name
;
msg_name
=
_mh_message_name
(
mhm
,
mhm
->
attr_flags
&
MU_ATTRIBUTE_DELETED
);
_mh_message_save
(
mhm
,
msg_name
);
free
(
msg_name
);
if
(
mhm
->
attr_flags
&
MU_ATTRIBUTE_DELETED
)
{
if
(
!
mhm
->
deleted
)
{
/* Delete original message */
msg_name
=
_mh_message_name
(
mhm
,
0
);
unlink
(
msg_name
);
free
(
msg_name
);
char
*
old_name
,
*
new_name
;
/* Rename original message */
old_name
=
_mh_message_name
(
mhm
,
0
);
new_name
=
_mh_message_name
(
mhm
,
1
);
rename
(
old_name
,
new_name
);
free
(
old_name
);
free
(
new_name
);
}
_mh_message_delete
(
mhd
,
mhm
);
}
else
if
(
mhm
->
deleted
)
else
if
(
mhm
->
attr_flags
&
MU_ATTRIBUTE_MODIFIED
)
{
/* Delete original file */
msg_name
=
_mh_message_name
(
mhm
,
1
);
unlink
(
msg_name
);
free
(
msg_name
);
_mh_attach_message
(
mailbox
,
mhm
,
NULL
);
mhm
->
deleted
=
mhm
->
attr_flags
&
MU_ATTRIBUTE_DELETED
;
_mh_message_save
(
mhd
,
mhm
,
1
);
}
mhm
=
next
;
}
...
...
@@ -885,9 +951,12 @@ mh_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount)
/* FIXME: .mh_sequences */
continue
;
case
','
:
continue
;
#if 0
attr_flags |= MU_ATTRIBUTE_DELETED;
namep = entry->d_name+1;
break;
#endif
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
namep
=
entry
->
d_name
;
...
...
@@ -1287,8 +1356,7 @@ mh_envelope_date (envelope_t envelope, char *buf, size_t len,
mh_pool_open
(
mhm
);
status
=
stream_readline
(
mhm
->
stream
,
buffer
,
sizeof
(
buffer
),
0
,
&
n
);
status
=
stream_readline
(
mhm
->
stream
,
buffer
,
sizeof
(
buffer
),
0
,
&
n
);
if
(
status
!=
0
)
{
if
(
psize
)
...
...
Please
register
or
sign in
to post a comment