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
9b610735
...
9b610735d22a860127a43321864274e2d74c605a
authored
2001-05-28 14:28:39 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
see ChangeLog
1 parent
83f6a439
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
337 additions
and
26 deletions
imap4d/copy.c
imap4d/create.c
imap4d/delete.c
imap4d/imap4d.c
imap4d/imap4d.h
imap4d/list.c
imap4d/login.c
imap4d/noop.c
imap4d/rename.c
imap4d/select.c
imap4d/status.c
imap4d/store.c
imap4d/util.c
imap4d/copy.c
View file @
9b61073
...
...
@@ -79,7 +79,13 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen)
mailbox_name
=
strdup
((
pw
)
?
pw
->
pw_name
:
""
);
}
else
mailbox_name
=
util_getfullpath
(
name
,
delim
);
mailbox_name
=
namespace_getfullpath
(
name
,
delim
);
if
(
!
mailbox_name
)
{
snprintf
(
resp
,
resplen
,
"NO Create failed."
);
return
RESP_NO
;
}
/* If the destination mailbox does not exist, a server should return
an error. */
...
...
imap4d/create.c
View file @
9b61073
...
...
@@ -52,7 +52,10 @@ imap4d_create (struct imap4d_command *command, char *arg)
return
util_finish
(
command
,
RESP_BAD
,
"Already exist"
);
/* Allocates memory. */
name
=
util_getfullpath
(
name
,
delim
);
name
=
namespace_getfullpath
(
name
,
delim
);
if
(
!
name
)
return
util_finish
(
command
,
RESP_NO
,
"Can not create mailbox"
);
/* It will fail if the mailbox already exists. */
if
(
access
(
name
,
F_OK
)
!=
0
)
...
...
imap4d/delete.c
View file @
9b61073
...
...
@@ -44,7 +44,9 @@ imap4d_delete (struct imap4d_command *command, char *arg)
return
util_finish
(
command
,
RESP_NO
,
"Already exist"
);
/* Allocates memory. */
name
=
util_getfullpath
(
name
,
delim
);
name
=
namespace_getfullpath
(
name
,
delim
);
if
(
!
name
)
return
util_finish
(
command
,
RESP_NO
,
"Can not remove"
);
if
(
remove
(
name
)
!=
0
)
{
...
...
imap4d/imap4d.c
View file @
9b61073
...
...
@@ -32,12 +32,14 @@ static struct option long_options[] =
{
"help"
,
no_argument
,
0
,
'h'
},
{
"inetd"
,
no_argument
,
0
,
'i'
},
{
"port"
,
required_argument
,
0
,
'p'
},
{
"other-namespace"
,
required_argument
,
0
,
'O'
},
{
"shared-namespace"
,
required_argument
,
0
,
'S'
},
{
"timeout"
,
required_argument
,
0
,
't'
},
{
"version"
,
no_argument
,
0
,
'v'
},
{
0
,
0
,
0
,
0
}
};
const
char
*
short_options
=
"d::hip:t:v"
;
const
char
*
short_options
=
"d::hip:t:v
O:P:S:
"
;
static
int
syslog_error_printer
__P
((
const
char
*
fmt
,
va_list
ap
));
static
int
imap4d_mainloop
__P
((
int
,
int
));
...
...
@@ -90,6 +92,14 @@ main (int argc, char **argv)
port
=
strtoul
(
optarg
,
NULL
,
10
);
break
;
case
'O'
:
set_namespace
(
NS_OTHER
,
optarg
);
break
;
case
'S'
:
set_namespace
(
NS_SHARED
,
optarg
);
break
;
case
't'
:
timeout
=
strtoul
(
optarg
,
NULL
,
10
);
break
;
...
...
imap4d/imap4d.h
View file @
9b61073
...
...
@@ -132,11 +132,18 @@ struct imap4d_command
#define ERR_TIMEOUT 3
#define ERR_SIGNAL 4
/* Namespace numbers */
#define NS_PRIVATE 0
#define NS_OTHER 1
#define NS_SHARED 2
#define NS_MAX 3
extern
struct
imap4d_command
imap4d_command_table
[];
extern
FILE
*
ofile
;
extern
unsigned
int
timeout
;
extern
mailbox_t
mbox
;
extern
char
*
homedir
;
extern
char
*
rootdir
;
extern
int
state
;
extern
volatile
size_t
children
;
...
...
@@ -169,6 +176,7 @@ extern int imap4d_store0 __P ((char *, int, char *, size_t));
extern
int
imap4d_subscribe
__P
((
struct
imap4d_command
*
,
char
*
));
extern
int
imap4d_uid
__P
((
struct
imap4d_command
*
,
char
*
));
extern
int
imap4d_unsubscribe
__P
((
struct
imap4d_command
*
,
char
*
));
extern
int
imap4d_namespace
__P
((
struct
imap4d_command
*
,
char
*
));
/* Synchronisation on simultenous access. */
extern
int
imap4d_sync
__P
((
void
));
...
...
imap4d/list.c
View file @
9b61073
...
...
@@ -141,7 +141,13 @@ imap4d_list (struct imap4d_command *command, char *arg)
}
/* Allocates. */
cwd
=
util_getfullpath
(
ref
,
delim
);
cwd
=
namespace_checkfullpath
(
ref
,
wcard
,
delim
);
if
(
!
cwd
)
{
free
(
ref
);
return
util_finish
(
command
,
RESP_NO
,
"The requested item could not be found."
);
}
/* If wcard match inbox return it too, part of the list. */
if
(
!*
ref
&&
(
match
(
"INBOX"
,
wcard
,
delim
)
...
...
@@ -156,6 +162,7 @@ imap4d_list (struct imap4d_command *command, char *arg)
free
(
cwd
);
free
(
ref
);
}
return
util_finish
(
command
,
RESP_OK
,
"Completed"
);
}
...
...
imap4d/login.c
View file @
9b61073
...
...
@@ -136,9 +136,10 @@ imap4d_login (struct imap4d_command *command, char *arg)
if
(
pw
->
pw_uid
>
1
)
setuid
(
pw
->
pw_uid
);
homedir
=
strdup
(
pw
->
pw_dir
);
homedir
=
util_normalize_path
(
strdup
(
pw
->
pw_dir
),
"/"
);
/* FIXME: Check for errors. */
chdir
(
homedir
);
namespace_init
(
pw
->
pw_dir
);
syslog
(
LOG_INFO
,
"User '%s' logged in"
,
username
);
return
util_finish
(
command
,
RESP_OK
,
"Completed"
);
}
...
...
imap4d/noop.c
View file @
9b61073
...
...
@@ -26,5 +26,6 @@ imap4d_noop (struct imap4d_command *command, char *arg)
return
util_finish
(
command
,
RESP_BAD
,
"Wrong state"
);
if
(
util_getword
(
arg
,
&
sp
))
return
util_finish
(
command
,
RESP_BAD
,
"Too many args"
);
imap4d_select_status
();
return
util_finish
(
command
,
RESP_OK
,
"Completed"
);
}
...
...
imap4d/rename.c
View file @
9b61073
...
...
@@ -50,7 +50,9 @@ imap4d_rename (struct imap4d_command *command, char *arg)
return
util_finish
(
command
,
RESP_NO
,
"Name Inbox is reservered"
);
/* Allocates memory. */
newname
=
util_getfullpath
(
newname
,
delim
);
newname
=
namespace_getfullpath
(
newname
,
delim
);
if
(
!
newname
)
return
util_finish
(
command
,
RESP_NO
,
"Permission denied"
);
/* It is an error to attempt to rename from a mailbox name that already
exist. */
...
...
@@ -118,14 +120,15 @@ imap4d_rename (struct imap4d_command *command, char *arg)
return
util_finish
(
command
,
RESP_OK
,
"Already exist"
);
}
oldname
=
util
_getfullpath
(
oldname
,
delim
);
oldname
=
namespace
_getfullpath
(
oldname
,
delim
);
/* It must exist. */
if
(
rename
(
oldname
,
newname
)
!=
0
)
if
(
!
oldname
||
rename
(
oldname
,
newname
)
!=
0
)
{
rc
=
RESP_NO
;
msg
=
"Failed"
;
}
if
(
oldname
)
free
(
oldname
);
free
(
newname
);
return
util_finish
(
command
,
rc
,
msg
);
...
...
imap4d/select.c
View file @
9b61073
...
...
@@ -17,6 +17,8 @@
#include "imap4d.h"
static
int
select_flags
;
/* select ::= "SELECT" SPACE mailbox */
int
...
...
@@ -67,17 +69,39 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags)
mailbox_name
=
strdup
(
"/dev/null"
);
}
else
mailbox_name
=
util_getfullpath
(
mailbox_name
,
"/"
);
mailbox_name
=
namespace_getfullpath
(
mailbox_name
,
"/"
);
if
(
!
mailbox_name
)
return
util_finish
(
command
,
RESP_NO
,
"Couldn't open mailbox"
);
if
(
mailbox_create
(
&
mbox
,
mailbox_name
)
==
0
&&
mailbox_open
(
mbox
,
flags
)
==
0
)
{
free
(
mailbox_name
);
select_flags
=
flags
;
state
=
STATE_SEL
;
imap4d_select_status
();
/* Need to set the state explicitely for select. */
return
util_send
(
"%s OK [%s] %s Completed
\r\n
"
,
command
->
tag
,
(
MU_STREAM_READ
==
flags
)
?
"READ-ONLY"
:
"READ-WRITE"
,
command
->
name
);
}
status
=
util_finish
(
command
,
RESP_NO
,
"Couldn't open %s"
,
mailbox_name
);
free
(
mailbox_name
);
return
status
;
}
/* The code is shared between select and noop */
void
imap4d_select_status
()
{
const
char
*
mflags
=
"
\\
Answered
\\
Flagged
\\
Deleted
\\
Seen
\\
Draft"
;
const
char
*
pflags
=
"
\\
Answered
\\
Deleted
\\
Seen"
;
unsigned
long
uidvalidity
=
0
;
size_t
count
=
0
,
recent
=
0
,
unseen
=
0
,
uidnext
=
0
;
free
(
mailbox_name
);
if
(
state
!=
STATE_SEL
)
return
;
mailbox_uidvalidity
(
mbox
,
&
uidvalidity
);
mailbox_uidnext
(
mbox
,
&
uidnext
);
...
...
@@ -95,17 +119,8 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags)
/* FIXME:
- '\*' can be supported if we use the attribute_set userflag()
- Answered is still not set in the mailbox code. */
if
(
flags
==
MU_STREAM_READ
)
if
(
select_flags
&
MU_STREAM_READ
)
util_out
(
RESP_OK
,
"[PERMANENTFLAGS ()] No Permanent flags"
);
else
util_out
(
RESP_OK
,
"[PERMANENTFLAGS (%s)] Permanent flags"
,
pflags
);
/* Need to set the state explicitely for select. */
state
=
STATE_SEL
;
return
util_send
(
"%s OK [%s] %s Completed
\r\n
"
,
command
->
tag
,
(
MU_STREAM_READ
==
flags
)
?
"READ-ONLY"
:
"READ-WRITE"
,
command
->
name
);
}
status
=
util_finish
(
command
,
RESP_NO
,
"Couldn't open %s"
,
mailbox_name
);
free
(
mailbox_name
);
return
status
;
}
...
...
imap4d/status.c
View file @
9b61073
...
...
@@ -51,7 +51,10 @@ imap4d_status (struct imap4d_command *command, char *arg)
mailbox_name
=
strdup
((
pw
)
?
pw
->
pw_name
:
""
);
}
else
mailbox_name
=
util_getfullpath
(
name
,
delim
);
mailbox_name
=
namespace_getfullpath
(
name
,
delim
);
if
(
!
mailbox_name
)
return
util_finish
(
command
,
RESP_NO
,
"Error opening mailbox"
);
status
=
mailbox_create_default
(
&
smbox
,
mailbox_name
);
if
(
status
==
0
)
...
...
imap4d/store.c
View file @
9b61073
...
...
@@ -138,6 +138,7 @@ imap4d_store0 (char *arg, int isuid, char *resp, size_t resplen)
}
attribute_set_flags
(
attr
,
type
);
}
attribute_set_flags
(
attr
,
MU_ATTRIBUTE_MODIFIED
);
flags
=
realloc
(
flags
,
strlen
(
flags
)
+
strlen
(
item
)
+
2
);
if
(
*
flags
)
strcat
(
flags
,
" "
);
...
...
imap4d/util.c
View file @
9b61073
...
...
@@ -152,6 +152,71 @@ util_tilde_expansion (const char *ref, const char *delim)
return
p
;
}
/* util_normalize_path: convert pathname containig relative paths specs (../)
into an equivalent absolute path. Strip trailing delimiter if present,
unless it is the only character left. E.g.:
/home/user/../smith --> /home/smith
/home/user/../.. --> /
FIXME: delim is superfluous. The function deals with unix filesystem
paths, so delim should be always "/" */
char
*
util_normalize_path
(
char
*
path
,
const
char
*
delim
)
{
int
len
;
char
*
p
;
if
(
!
path
)
return
path
;
len
=
strlen
(
path
);
/* Empty string is returned as is */
if
(
len
==
0
)
return
path
;
/* delete trailing delimiter if any */
if
(
len
&&
path
[
len
-
1
]
==
delim
[
0
])
path
[
len
-
1
]
=
0
;
/* Eliminate any /../ */
for
(
p
=
strchr
(
path
,
'.'
);
p
;
p
=
strchr
(
p
,
'.'
))
{
if
(
p
>
path
&&
p
[
-
1
]
==
delim
[
0
])
{
if
(
p
[
1
]
==
'.'
&&
(
p
[
2
]
==
0
||
p
[
2
]
==
delim
[
0
]))
/* found */
{
char
*
q
,
*
s
;
/* Find previous delimiter */
for
(
q
=
p
-
2
;
*
q
!=
delim
[
0
]
&&
q
>=
path
;
q
--
)
;
if
(
q
<
path
)
break
;
/* Copy stuff */
s
=
p
+
2
;
p
=
q
;
while
(
*
q
++
=
*
s
++
)
;
continue
;
}
}
p
++
;
}
if
(
path
[
0
]
==
0
)
{
path
[
0
]
=
delim
[
0
];
path
[
1
]
=
0
;
}
return
path
;
}
/* Get the absolute path. */
/* NOTE: Path is allocated and must be free()d by the caller. */
char
*
...
...
@@ -165,7 +230,7 @@ util_getfullpath (char *name, const char *delim)
free
(
p
);
p
=
s
;
}
return
p
;
return
util_normalize_path
(
p
,
delim
)
;
}
/* Return in set an allocated array contain (n) numbers, for imap messsage set
...
...
@@ -226,7 +291,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid)
{
long
tmp
=
low
;
tmp
-=
2
;
if
(
tmp
<
=
0
||
val
==
0
)
if
(
tmp
<
0
||
val
==
0
)
{
free
(
*
set
);
*
n
=
0
;
...
...
@@ -245,7 +310,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid)
}
else
{
status
=
add2set
(
set
,
n
,
val
);
status
=
add2set
(
set
,
n
,
val
);
if
(
status
!=
0
)
return
status
;
}
...
...
@@ -397,7 +462,7 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...)
va_start
(
ap
,
format
);
status
=
vfprintf
(
ofile
,
buf
,
ap
);
va_end
(
ap
);
va_end
(
ap
);
free
(
buf
);
/* Reset the state. */
new_state
=
(
rc
==
RESP_OK
)
?
command
->
success
:
command
->
failure
;
...
...
@@ -610,3 +675,189 @@ add2set (size_t **set, int *n, unsigned long val)
(
*
n
)
++
;
return
0
;
}
static
const
char
*
months
[]
=
{
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
};
#define c2d(c) (c-'0')
int
util_parse_internal_date
(
char
*
date
,
time_t
*
timep
)
{
struct
tm
tm
;
char
*
save
;
int
n
,
i
;
int
year
,
day
,
hour
,
min
,
sec
;
char
mon
[
4
];
char
sign
[
2
];
char
tzs
[
6
];
time_t
time
;
memset
(
&
tm
,
0
,
sizeof
(
tm
));
n
=
sscanf
(
date
,
"%2d-%3s-%4d %2d:%2d:%2d %5s
\n
"
,
&
day
,
mon
,
&
year
,
&
hour
,
&
min
,
&
sec
,
&
tzs
);
switch
(
n
)
{
case
3
:
case
6
:
case
7
:
break
;
default:
return
1
;
}
tm
.
tm_mday
=
day
;
for
(
i
=
0
;
i
<
11
;
i
++
)
if
(
strncmp
(
months
[
i
],
mon
,
3
)
==
0
)
break
;
if
(
i
==
12
)
return
1
;
tm
.
tm_mon
=
i
;
tm
.
tm_year
=
(
year
<
1900
)
?
year
:
year
-
1900
;
if
(
n
>=
6
)
{
tm
.
tm_hour
=
hour
;
tm
.
tm_min
=
min
;
tm
.
tm_sec
=
sec
;
}
tm
.
tm_isdst
=
-
1
;
/* unknown. */
time
=
mktime
(
&
tm
);
if
(
time
==
(
time_t
)
-
1
)
return
2
;
if
(
n
==
7
)
{
int
sign
;
int
tz
;
if
(
strlen
(
tzs
)
!=
5
)
return
3
;
for
(
i
=
1
;
i
<=
4
;
i
++
)
if
(
!
isdigit
(
tzs
[
i
]))
return
3
;
tz
=
(
c2d
(
tzs
[
1
])
*
10
+
c2d
(
tzs
[
2
]))
*
60
+
c2d
(
tzs
[
3
])
*
10
+
c2d
(
tzs
[
4
]);
if
(
tzs
[
0
]
==
'-'
)
tz
=
-
tz
;
else
if
(
tzs
[
0
]
!=
'+'
)
return
4
;
time
-=
tz
*
60
;
}
*
timep
=
time
;
return
0
;
}
int
util_parse_header_date
(
char
*
date
,
time_t
*
timep
)
{
struct
tm
tm
;
char
*
save
;
int
n
,
i
;
int
year
,
day
,
hour
,
min
,
sec
;
char
wday
[
5
];
char
mon
[
4
];
char
sign
[
2
];
char
tzs
[
6
];
time_t
time
;
memset
(
&
tm
,
0
,
sizeof
(
tm
));
n
=
sscanf
(
date
,
"%3s, %2d %3s %4d %2d:%2d:%2d %5s"
,
wday
,
&
day
,
mon
,
&
year
,
&
hour
,
&
min
,
&
sec
,
&
tzs
);
if
(
n
<
7
)
return
1
;
tm
.
tm_mday
=
day
;
for
(
i
=
0
;
i
<
11
;
i
++
)
if
(
strncmp
(
months
[
i
],
mon
,
3
)
==
0
)
break
;
if
(
i
==
12
)
return
1
;
tm
.
tm_mon
=
i
;
tm
.
tm_year
=
(
year
<
1900
)
?
year
:
year
-
1900
;
if
(
n
>=
6
)
{
tm
.
tm_hour
=
hour
;
tm
.
tm_min
=
min
;
tm
.
tm_sec
=
sec
;
}
tm
.
tm_isdst
=
-
1
;
/* unknown. */
time
=
mktime
(
&
tm
);
if
(
time
==
(
time_t
)
-
1
)
return
2
;
if
(
n
==
8
)
{
int
sign
;
int
tz
;
if
(
strlen
(
tzs
)
!=
5
)
return
3
;
for
(
i
=
1
;
i
<=
4
;
i
++
)
if
(
!
isdigit
(
tzs
[
i
]))
return
3
;
tz
=
(
c2d
(
tzs
[
1
])
*
10
+
c2d
(
tzs
[
2
]))
*
60
+
c2d
(
tzs
[
3
])
*
10
+
c2d
(
tzs
[
4
]);
if
(
tzs
[
0
]
==
'-'
)
tz
=
-
tz
;
else
if
(
tzs
[
0
]
!=
'+'
)
return
4
;
time
-=
tz
*
60
;
}
*
timep
=
time
;
return
0
;
}
int
util_parse_rfc822_date
(
char
*
date
,
time_t
*
timep
)
{
int
year
,
mon
,
day
,
hour
,
min
,
sec
;
int
offt
;
int
i
;
struct
tm
tm
;
char
month
[
5
];
char
wday
[
5
];
month
[
0
]
=
'\0'
;
wday
[
0
]
=
'\0'
;
day
=
mon
=
year
=
hour
=
min
=
sec
=
offt
=
0
;
/* RFC822 Date: format. */
if
(
sscanf
(
date
,
"%3s %3s %2d %2d:%2d:%2d %d
\n
"
,
wday
,
month
,
&
day
,
&
hour
,
&
min
,
&
sec
,
&
year
)
!=
7
)
return
1
;
tm
.
tm_sec
=
sec
;
tm
.
tm_min
=
min
;
tm
.
tm_hour
=
hour
;
for
(
i
=
0
;
i
<
12
;
i
++
)
{
if
(
strncasecmp
(
month
,
months
[
i
],
3
)
==
0
)
{
mon
=
i
;
break
;
}
}
tm
.
tm_mday
=
day
;
tm
.
tm_mon
=
mon
;
tm
.
tm_year
=
(
year
>
1900
)
?
year
-
1900
:
year
;
tm
.
tm_yday
=
0
;
/* unknown. */
tm
.
tm_wday
=
0
;
/* unknown. */
tm
.
tm_isdst
=
-
1
;
/* unknown. */
/* What to do the timezone? */
*
timep
=
mktime
(
&
tm
);
return
0
;
}
...
...
Please
register
or
sign in
to post a comment