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
6760ea1e
...
6760ea1ebc3f2f310e2942d61b6c19b367b767f3
authored
2003-02-22 22:27:06 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Minor change.
1 parent
af7a57cd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
243 additions
and
2 deletions
mh/mh_stream.c
mh/mh_stream.c
View file @
6760ea1
...
...
@@ -16,13 +16,26 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file implements an MH draftfile stream: a read-only stream used
to transparently pass MH draftfiles to
the
mailers. The only difference
to transparently pass MH draftfiles to mailers. The only difference
between the usual RFC822 and MH draft is that the latter allows to use
a string of dashes to separate the headers from the body. */
#include <mh.h>
#include <mailutils/stream.h>
static
int
_mh_delim
(
char
*
str
)
{
if
(
str
[
0
]
==
'-'
)
{
for
(;
*
str
==
'-'
;
str
++
)
;
for
(;
*
str
==
' '
||
*
str
==
'\t'
;
str
++
)
;
}
return
str
[
0
]
==
'\n'
;
}
struct
_mhdraft_stream
{
stream_t
stream
;
/* Actual stream */
size_t
mark_offset
;
/* Offset of the header separator */
...
...
@@ -58,7 +71,7 @@ _mhdraft_readline (stream_t stream, char *optr, size_t osize,
{
int
rc
;
size_t
n
;
size_t
rdsize
=
s
->
mark_offset
-
offset
;
size_t
rdsize
=
s
->
mark_offset
-
offset
+
1
;
rc
=
stream_readline
(
s
->
stream
,
optr
,
rdsize
,
offset
,
&
n
);
if
(
rc
==
0
)
{
...
...
@@ -160,3 +173,231 @@ mhdraft_stream_create (stream_t *stream, stream_t src, int flags)
}
/* *************************** MH draft message **************************** */
char
*
skipws
(
char
*
p
,
size_t
off
)
{
int
len
;
for
(
p
+=
off
;
*
p
&&
isspace
(
*
p
);
p
++
)
;
len
=
strlen
(
p
);
if
(
len
>
0
&&
p
[
len
-
1
]
==
'\n'
)
p
[
len
-
1
]
=
0
;
return
p
;
}
struct
_mhdraft_message
{
char
*
from
;
char
*
date
;
size_t
body_start
;
size_t
body_end
;
};
static
int
restore_envelope
(
stream_t
str
,
struct
_mhdraft_message
**
pmenv
)
{
size_t
offset
=
0
;
char
*
from
=
NULL
;
char
*
env_from
=
NULL
;
char
*
env_date
=
NULL
;
int
rc
;
char
buffer
[
80
];
size_t
len
;
size_t
body_start
,
body_end
;
while
((
rc
=
stream_readline
(
str
,
buffer
,
sizeof
buffer
,
offset
,
&
len
))
==
0
&&
len
>
0
)
{
if
(
buffer
[
0
]
==
'\n'
)
break
;
buffer
[
len
]
=
0
;
offset
+=
len
;
if
(
strncasecmp
(
buffer
,
MU_HEADER_FROM
,
sizeof
(
MU_HEADER_FROM
)
-
1
)
==
0
)
from
=
strdup
(
skipws
(
buffer
,
sizeof
(
MU_HEADER_FROM
)));
else
if
(
strncasecmp
(
buffer
,
MU_HEADER_ENV_SENDER
,
sizeof
(
MU_HEADER_ENV_SENDER
)
-
1
)
==
0
)
env_from
=
strdup
(
skipws
(
buffer
,
sizeof
(
MU_HEADER_ENV_SENDER
)));
else
if
(
strncasecmp
(
buffer
,
MU_HEADER_ENV_DATE
,
sizeof
(
MU_HEADER_ENV_DATE
)
-
1
)
==
0
)
env_date
=
strdup
(
skipws
(
buffer
,
sizeof
(
MU_HEADER_ENV_DATE
)));
}
body_start
=
offset
+
1
;
stream_size
(
str
,
&
body_end
);
if
(
!
env_from
)
{
if
(
from
)
{
address_t
addr
;
address_create
(
&
addr
,
from
);
if
(
!
addr
||
address_aget_email
(
addr
,
1
,
&
env_from
))
env_from
=
strdup
(
"GNU-MH"
);
address_destroy
(
&
addr
);
}
else
env_from
=
strdup
(
"GNU-MH"
);
}
if
(
!
env_date
)
{
struct
tm
*
tm
;
time_t
t
;
char
date
[
80
];
time
(
&
t
);
tm
=
gmtime
(
&
t
);
strftime
(
date
,
sizeof
(
date
),
"%a %b %e %H:%M:%S %Y"
,
tm
);
env_date
=
strdup
(
date
);
}
*
pmenv
=
xmalloc
(
sizeof
(
**
pmenv
)
+
strlen
(
env_from
)
+
strlen
(
env_date
)
+
2
);
(
*
pmenv
)
->
from
=
(
char
*
)
(
*
pmenv
+
1
);
(
*
pmenv
)
->
date
=
(
char
*
)
((
*
pmenv
)
->
from
+
strlen
(
env_from
)
+
1
);
strcpy
((
*
pmenv
)
->
from
,
env_from
);
strcpy
((
*
pmenv
)
->
date
,
env_date
);
(
*
pmenv
)
->
body_start
=
body_start
;
(
*
pmenv
)
->
body_end
=
body_end
;
free
(
env_from
);
free
(
env_date
);
free
(
from
);
return
0
;
}
static
int
_env_msg_date
(
envelope_t
envelope
,
char
*
buf
,
size_t
len
,
size_t
*
pnwrite
)
{
message_t
msg
=
envelope_get_owner
(
envelope
);
struct
_mhdraft_message
*
env
=
message_get_owner
(
msg
);
if
(
!
env
||
!
env
->
date
)
return
EINVAL
;
strncpy
(
buf
,
env
->
date
,
len
);
buf
[
len
-
1
]
=
0
;
return
0
;
}
static
int
_env_msg_sender
(
envelope_t
envelope
,
char
*
buf
,
size_t
len
,
size_t
*
pnwrite
)
{
message_t
msg
=
envelope_get_owner
(
envelope
);
struct
_mhdraft_message
*
env
=
message_get_owner
(
msg
);
if
(
!
env
||
!
env
->
from
)
return
EINVAL
;
strncpy
(
buf
,
env
->
from
,
len
);
buf
[
len
-
1
]
=
0
;
return
0
;
}
static
int
_body_size
(
body_t
body
,
size_t
*
size
)
{
message_t
msg
=
body_get_owner
(
body
);
struct
_mhdraft_message
*
mp
=
message_get_owner
(
msg
);
if
(
size
)
*
size
=
mp
->
body_end
-
mp
->
body_start
;
return
0
;
}
static
int
_body_read
(
stream_t
stream
,
char
*
optr
,
size_t
osize
,
off_t
offset
,
size_t
*
nbytes
)
{
body_t
body
=
stream_get_owner
(
stream
);
message_t
msg
=
body_get_owner
(
body
);
struct
_mhdraft_message
*
mp
=
message_get_owner
(
msg
);
stream_t
str
;
message_get_stream
(
msg
,
&
str
);
return
stream_read
(
str
,
optr
,
osize
,
mp
->
body_start
+
offset
,
nbytes
);
}
static
int
_body_readline
(
stream_t
stream
,
char
*
optr
,
size_t
osize
,
off_t
offset
,
size_t
*
nbytes
)
{
message_t
msg
=
stream_get_owner
(
stream
);
struct
_mhdraft_message
*
mp
=
message_get_owner
(
msg
);
stream_t
str
;
message_get_stream
(
msg
,
&
str
);
return
stream_readline
(
str
,
optr
,
osize
,
mp
->
body_start
+
offset
,
nbytes
);
}
static
int
_body_stream_size
(
stream_t
stream
,
off_t
*
psize
)
{
message_t
msg
=
stream_get_owner
(
stream
);
struct
_mhdraft_message
*
mp
=
message_get_owner
(
msg
);
if
(
psize
)
*
psize
=
mp
->
body_end
-
mp
->
body_start
;
return
0
;
}
message_t
mh_stream_to_message
(
stream_t
instream
)
{
struct
_mhdraft_message
*
mp
;
envelope_t
env
;
message_t
msg
;
body_t
body
;
stream_t
bstream
;
stream_t
draftstream
;
int
rc
;
if
((
rc
=
mhdraft_stream_create
(
&
draftstream
,
instream
,
0
)))
{
mh_error
(
_
(
"cannot create draft message stream: %s"
),
mu_strerror
(
rc
));
return
NULL
;
}
if
((
rc
=
stream_open
(
draftstream
)))
{
mh_error
(
_
(
"cannot open draft message stream: %s"
),
mu_strerror
(
rc
));
stream_destroy
(
&
draftstream
,
stream_get_owner
(
draftstream
));
return
NULL
;
}
restore_envelope
(
draftstream
,
&
mp
);
if
(
message_create
(
&
msg
,
mp
))
return
NULL
;
message_set_stream
(
msg
,
draftstream
,
mp
);
if
(
envelope_create
(
&
env
,
msg
))
return
NULL
;
envelope_set_date
(
env
,
_env_msg_date
,
msg
);
envelope_set_sender
(
env
,
_env_msg_sender
,
msg
);
message_set_envelope
(
msg
,
env
,
mp
);
body_create
(
&
body
,
msg
);
stream_create
(
&
bstream
,
MU_STREAM_RDWR
|
MU_STREAM_SEEKABLE
,
body
);
stream_set_read
(
bstream
,
_body_read
,
body
);
stream_set_readline
(
bstream
,
_body_readline
,
body
);
stream_set_size
(
bstream
,
_body_stream_size
,
body
);
body_set_stream
(
body
,
bstream
,
msg
);
body_set_size
(
body
,
_body_size
,
msg
);
message_set_body
(
msg
,
body
,
mp
);
return
msg
;
}
...
...
Please
register
or
sign in
to post a comment