@ -113,13 +113,34 @@ maildir_parse_flags( const char *info_prefix, const char *base )
return flags ;
return flags ;
}
}
static int
maildir_ensure_path ( maildir_store_conf_t * conf )
{
if ( ! conf - > gen . path ) {
error ( " Maildir error: store '%s' has no Path \n " , conf - > gen . name ) ;
conf - > failed = FAIL_FINAL ;
return - 1 ;
}
return 0 ;
}
/* Subdirs of INBOX include a leading slash. */
/* Path includes a trailing slash, Inbox does not. */
static char *
static char *
maildir_join_path ( maildir_store_conf_t * conf , const char * prefix , const char * box )
maildir_join_path ( maildir_store_conf_t * conf , int in_inbo x, const char * box )
{
{
char * out , * p ;
char * out , * p ;
int pl , bl , n , sub = 0 ;
const char * prefix ;
int pl , bl , n ;
char c ;
char c ;
if ( in_inbox | | conf - > sub_style = = SUB_MAILDIRPP ) {
prefix = conf - > inbox ;
} else {
if ( maildir_ensure_path ( conf ) < 0 )
return 0 ;
prefix = conf - > gen . path ;
}
pl = strlen ( prefix ) ;
pl = strlen ( prefix ) ;
for ( bl = 0 , n = 0 ; ( c = box [ bl ] ) ; bl + + )
for ( bl = 0 , n = 0 ; ( c = box [ bl ] ) ; bl + + )
if ( c = = ' / ' ) {
if ( c = = ' / ' ) {
@ -134,24 +155,33 @@ maildir_join_path( maildir_store_conf_t *conf, const char *prefix, const char *b
conf - > gen . name , box ) ;
conf - > gen . name , box ) ;
return 0 ;
return 0 ;
}
}
switch ( conf - > sub_style ) {
case SUB_VERBATIM :
n = 0 ;
break ;
case SUB_MAILDIRPP :
n = 2 ;
break ;
default : /* SUB_LEGACY and SUB_UNSET */
break ;
}
out = nfmalloc ( pl + bl + n + 1 ) ;
out = nfmalloc ( pl + bl + n + 1 ) ;
memcpy ( out , prefix , pl ) ;
memcpy ( out , prefix , pl ) ;
p = out + pl ;
p = out + pl ;
if ( conf - > sub_style = = SUB_MAILDIRPP ) {
* p + + = ' / ' ;
* p + + = ' . ' ;
}
while ( ( c = * box + + ) ) {
while ( ( c = * box + + ) ) {
if ( c = = ' / ' ) {
if ( c = = ' / ' ) {
switch ( conf - > sub_style ) {
switch ( conf - > sub_style ) {
case SUB_VERBATIM :
case SUB_VERBATIM :
* p + + = c ;
* p + + = c ;
break ;
break ;
case SUB_MAILDIRPP :
if ( ! sub ) {
sub = 1 ;
* p + + = c ;
}
* p + + = ' . ' ;
break ;
case SUB_LEGACY :
case SUB_LEGACY :
* p + + = c ;
* p + + = c ;
/* fallthrough */
default : /* SUB_MAILDIRPP */
* p + + = ' . ' ;
* p + + = ' . ' ;
break ;
break ;
}
}
@ -163,17 +193,6 @@ maildir_join_path( maildir_store_conf_t *conf, const char *prefix, const char *b
return out ;
return out ;
}
}
static int
maildir_ensure_path ( maildir_store_conf_t * conf )
{
if ( ! conf - > gen . path ) {
error ( " Maildir error: store '%s' has no Path \n " , conf - > gen . name ) ;
conf - > failed = FAIL_FINAL ;
return - 1 ;
}
return 0 ;
}
static int
static int
maildir_validate_path ( maildir_store_conf_t * conf )
maildir_validate_path ( maildir_store_conf_t * conf )
{
{
@ -212,15 +231,9 @@ maildir_connect_store( store_t *gctx,
cb ( DRV_STORE_BAD , aux ) ;
cb ( DRV_STORE_BAD , aux ) ;
return ;
return ;
}
}
if ( conf - > gen . trash ) {
if ( conf - > gen . trash & & ! ( ctx - > trash = maildir_join_path ( conf , 0 , conf - > gen . trash ) ) ) {
if ( maildir_ensure_path ( conf ) < 0 ) {
cb ( DRV_STORE_BAD , aux ) ;
cb ( DRV_STORE_BAD , aux ) ;
return ;
return ;
}
if ( ! ( ctx - > trash = maildir_join_path ( conf , conf - > gen . path , conf - > gen . trash ) ) ) {
cb ( DRV_STORE_BAD , aux ) ;
return ;
}
}
}
cb ( DRV_OK , aux ) ;
cb ( DRV_OK , aux ) ;
}
}
@ -325,6 +338,8 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags,
return - 1 ;
return - 1 ;
}
}
} else {
} else {
char * effName = name ;
int nameOff = 0 ;
if ( style = = SUB_MAILDIRPP | | style = = SUB_LEGACY ) {
if ( style = = SUB_MAILDIRPP | | style = = SUB_LEGACY ) {
if ( * ent = = ' . ' ) {
if ( * ent = = ' . ' ) {
if ( ! isBox )
if ( ! isBox )
@ -334,15 +349,27 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags,
if ( isBox )
if ( isBox )
continue ;
continue ;
}
}
if ( style = = SUB_MAILDIRPP ) {
if ( * ent = = ' . ' ) {
if ( ! ( flags & LIST_INBOX ) )
continue ;
ent + + ;
} else {
if ( ! ( flags & ( LIST_PATH | LIST_PATH_MAYBE ) ) )
continue ;
effName = name + 6 ;
nameOff = 6 ;
}
}
}
}
nl = nameLen + nfsnprintf ( name + nameLen , _POSIX_PATH_MAX - nameLen , " %s " , ent ) ;
nl = nameLen + nfsnprintf ( name + nameLen , _POSIX_PATH_MAX - nameLen , " %s " , ent ) ;
if ( style = = SUB_MAILDIRPP & & isBox ) {
if ( style = = SUB_MAILDIRPP ) {
for ( i = nameLen ; i < nl ; i + + ) {
for ( i = nameLen ; i < nl ; i + + ) {
if ( name [ i ] = = ' . ' )
if ( name [ i ] = = ' . ' )
name [ i ] = ' / ' ;
name [ i ] = ' / ' ;
}
}
}
}
if ( ! nameLen & & equals ( name , nl , " INBOX " , 5 ) & & ( ! name [ 5 ] | | name [ 5 ] = = ' / ' ) ) {
if ( nameLen = = nameOff & & equals ( effN ame, nl - nameOff , " INBOX " , 5 ) & & ( ! effN ame[ 5 ] | | effN ame[ 5 ] = = ' / ' ) ) {
path [ pathLen ] = 0 ;
path [ pathLen ] = 0 ;
warn ( " Maildir warning: ignoring INBOX in %s \n " , path ) ;
warn ( " Maildir warning: ignoring INBOX in %s \n " , path ) ;
continue ;
continue ;
@ -350,9 +377,9 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags,
path [ pl + + ] = ' / ' ;
path [ pl + + ] = ' / ' ;
nfsnprintf ( path + pl , _POSIX_PATH_MAX - pl , " cur " ) ;
nfsnprintf ( path + pl , _POSIX_PATH_MAX - pl , " cur " ) ;
if ( ! stat ( path , & st ) & & S_ISDIR ( st . st_mode ) )
if ( ! stat ( path , & st ) & & S_ISDIR ( st . st_mode ) )
add_string_list ( & gctx - > boxes , n ame ) ;
add_string_list ( & gctx - > boxes , effN ame ) ;
if ( style = = SUB_MAILDIRPP & & isBox ) {
if ( style = = SUB_MAILDIRPP ) {
/* Maildir++ sub folder - don't recurse further. */
/* Maildir++ folder - don't recurse further. */
continue ;
continue ;
}
}
path [ pl ] = 0 ;
path [ pl ] = 0 ;
@ -372,7 +399,8 @@ maildir_list_inbox( store_t *gctx, int flags, const char *basePath )
{
{
char path [ _POSIX_PATH_MAX ] , name [ _POSIX_PATH_MAX ] ;
char path [ _POSIX_PATH_MAX ] , name [ _POSIX_PATH_MAX ] ;
add_string_list ( & gctx - > boxes , " INBOX " ) ;
if ( flags & LIST_INBOX )
add_string_list ( & gctx - > boxes , " INBOX " ) ;
return maildir_list_recurse (
return maildir_list_recurse (
gctx , 1 , flags , 0 , 0 , basePath , basePath ? strlen ( basePath ) - 1 : 0 ,
gctx , 1 , flags , 0 , 0 , basePath , basePath ? strlen ( basePath ) - 1 : 0 ,
path , nfsnprintf ( path , _POSIX_PATH_MAX , " %s/ " , ( ( maildir_store_conf_t * ) gctx - > conf ) - > inbox ) ,
path , nfsnprintf ( path , _POSIX_PATH_MAX , " %s/ " , ( ( maildir_store_conf_t * ) gctx - > conf ) - > inbox ) ,
@ -396,9 +424,12 @@ static void
maildir_list_store ( store_t * gctx , int flags ,
maildir_list_store ( store_t * gctx , int flags ,
void ( * cb ) ( int sts , void * aux ) , void * aux )
void ( * cb ) ( int sts , void * aux ) , void * aux )
{
{
if ( ( ( ( flags & LIST_PATH ) | | ( ( flags & LIST_PATH_MAYBE ) & & gctx - > conf - > path ) )
maildir_store_conf_t * conf = ( maildir_store_conf_t * ) gctx - > conf ;
& & maildir_list_path ( gctx , flags , ( ( maildir_store_conf_t * ) gctx - > conf ) - > inbox ) < 0 ) | |
if ( ( ( ( ( flags & LIST_PATH ) & & conf - > sub_style ! = SUB_MAILDIRPP )
( ( flags & LIST_INBOX ) & & maildir_list_inbox ( gctx , flags , gctx - > conf - > path ) < 0 ) ) {
| | ( ( flags & LIST_PATH_MAYBE ) & & gctx - > conf - > path ) )
& & maildir_list_path ( gctx , flags , conf - > inbox ) < 0 ) | |
( ( ( flags & LIST_INBOX ) | | conf - > sub_style = = SUB_MAILDIRPP )
& & maildir_list_inbox ( gctx , flags , gctx - > conf - > path ) < 0 ) ) {
maildir_invoke_bad_callback ( gctx ) ;
maildir_invoke_bad_callback ( gctx ) ;
cb ( DRV_CANCELED , aux ) ;
cb ( DRV_CANCELED , aux ) ;
} else {
} else {
@ -1111,14 +1142,16 @@ maildir_select_box( store_t *gctx, const char *name )
# endif /* USE_DB */
# endif /* USE_DB */
ctx - > fresh [ 0 ] = ctx - > fresh [ 1 ] = 0 ;
ctx - > fresh [ 0 ] = ctx - > fresh [ 1 ] = 0 ;
if ( starts_with ( name , - 1 , " INBOX " , 5 ) & & ( ! name [ 5 ] | | name [ 5 ] = = ' / ' ) ) {
if ( starts_with ( name , - 1 , " INBOX " , 5 ) & & ( ! name [ 5 ] | | name [ 5 ] = = ' / ' ) ) {
gctx - > path = maildir_join_path ( conf , conf - > inbox , name + 5 ) ;
if ( ! name [ 5 ] ) {
ctx - > is_inbox = ! name [ 5 ] ;
g ctx- > path = nfstrdup ( conf - > inbox ) ;
} else {
ctx - > is_inbox = 1 ;
if ( maildir_ensure_path ( conf ) < 0 ) {
} else {
gctx - > path = 0 ;
gctx - > path = maildir_join_path ( conf , 1 , name + 5 ) ;
return DRV_CANCELED ;
ctx - > is_inbox = 0 ;
}
}
gctx - > path = maildir_join_path ( conf , conf - > gen . path , name ) ;
} else {
if ( ! ( gctx - > path = maildir_join_path ( conf , 0 , name ) ) )
return DRV_CANCELED ;
ctx - > is_inbox = 0 ;
ctx - > is_inbox = 0 ;
}
}
return gctx - > path ? DRV_OK : DRV_BOX_BAD ;
return gctx - > path ? DRV_OK : DRV_BOX_BAD ;
@ -1741,6 +1774,10 @@ maildir_parse_store( conffile_t *cfg, store_conf_t **storep )
parse_generic_store ( & store - > gen , cfg ) ;
parse_generic_store ( & store - > gen , cfg ) ;
if ( ! store - > inbox )
if ( ! store - > inbox )
store - > inbox = expand_strdup ( " ~/Maildir " ) ;
store - > inbox = expand_strdup ( " ~/Maildir " ) ;
if ( store - > sub_style = = SUB_MAILDIRPP & & store - > gen . path ) {
error ( " Maildir store '%s': Setting Path is incompatible with 'SubFolders Maildir++' \n " , store - > gen . name ) ;
cfg - > err = 1 ;
}
nfasprintf ( & store - > info_prefix , " %c2, " , store - > info_delimiter ) ;
nfasprintf ( & store - > info_prefix , " %c2, " , store - > info_delimiter ) ;
nfasprintf ( & store - > info_stop , " %c, " , store - > info_delimiter ) ;
nfasprintf ( & store - > info_stop , " %c, " , store - > info_delimiter ) ;
* storep = & store - > gen ;
* storep = & store - > gen ;