Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F120840580
acapmbox.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None
acapmbox.c
View Options
#include
<stdlib.h>
#include
<stdio.h>
#include
<string.h>
#include
<syslog.h>
#include
<acap.h>
#include
"acapmbox.h"
#include
"mailbox.h"
#include
"assert.h"
#include
"config.h"
#include
"imap_err.h"
extern
sasl_callback_t
*
mysasl_callbacks
(
const
char
*
username
,
const
char
*
authname
,
const
char
*
realm
,
const
char
*
password
);
const
char
*
global_dataset
=
"/mb"
;
struct
acapmbox_handle_s
{
acap_conn_t
*
conn
;
};
char
*
acapmbox_get_url
(
char
*
name
)
{
static
char
url
[
MAX_MAILBOX_PATH
];
snprintf
(
url
,
sizeof
(
url
),
"imap://%s/%s"
,
config_servername
,
name
);
return
url
;
}
/* xxx
this should probably vary depending on whether it's a private
mailbox or a bboard, and it should default to
"bb+bboard.name@server.name" */
char
*
acapmbox_get_postaddr
(
char
*
name
)
{
const
char
*
postspec
=
config_getstring
(
"postspec"
,
NULL
);
static
char
postaddr
[
MAX_MAILBOX_PATH
];
if
(
postspec
)
{
snprintf
(
postaddr
,
sizeof
(
postaddr
),
postspec
,
name
);
}
else
{
snprintf
(
postaddr
,
sizeof
(
postaddr
),
"bb+%s@%s"
,
name
,
config_servername
);
}
return
postaddr
;
}
acapmbox_handle_t
*
acapmbox_get_handle
(
void
)
{
int
r
;
char
str
[
2048
];
const
char
*
acapserver
;
static
acapmbox_handle_t
*
cached_conn
=
NULL
;
const
char
*
user
;
sasl_callback_t
*
cb
;
acapserver
=
config_getstring
(
"acap_server"
,
NULL
);
if
(
!
acapserver
)
return
NULL
;
if
(
cached_conn
)
{
/* xxx verify cached_conn is still a valid connection */
return
cached_conn
;
}
cached_conn
=
(
acapmbox_handle_t
*
)
xmalloc
(
sizeof
(
acapmbox_handle_t
));
cached_conn
->
conn
=
NULL
;
user
=
config_getstring
(
"acap_username"
,
NULL
);
if
(
user
==
NULL
)
{
syslog
(
LOG_ERR
,
"unable to find option acap_username"
);
return
cached_conn
;
}
cb
=
mysasl_callbacks
(
user
,
config_getstring
(
"acap_authname"
,
user
),
config_getstring
(
"acap_realm"
,
NULL
),
config_getstring
(
"acap_password"
,
NULL
));
r
=
sasl_client_init
(
cb
);
if
(
r
!=
SASL_OK
)
{
syslog
(
LOG_ERR
,
"sasl_client_init() failed: %s"
,
sasl_errstring
(
r
,
NULL
,
NULL
));
return
cached_conn
;
}
snprintf
(
str
,
sizeof
(
str
),
"acap://%s@%s/"
,
user
,
acapserver
);
r
=
acap_conn_connect
(
str
,
&
(
cached_conn
->
conn
));
if
(
r
!=
ACAP_OK
)
{
syslog
(
LOG_ERR
,
"acap_conn_connect() failed: %s"
,
error_message
(
r
));
acap_conn_close
(
cached_conn
->
conn
);
cached_conn
->
conn
=
NULL
;
return
cached_conn
;
}
syslog
(
LOG_INFO
,
"ACAP: opened connection to %s"
,
acapserver
);
return
cached_conn
;
}
void
acapmbox_release_handle
(
acapmbox_handle_t
*
handle
)
{
/* NOOP */
}
void
acapmbox_cb
(
acap_result_t
res
,
void
*
rock
)
{
printf
(
"in callback
\n
"
);
}
/*
* Create the full dataset with entry name
*
*/
char
*
create_full_dataset_name
(
char
*
mailbox_name
)
{
static
char
fullname
[
MAX_MAILBOX_PATH
];
snprintf
(
fullname
,
sizeof
(
fullname
),
"%s/%s"
,
global_dataset
,
mailbox_name
);
return
fullname
;
}
int
add_attr
(
skiplist
*
sl
,
char
*
name
,
char
*
value
)
{
acap_attribute_t
*
tmpattr
;
tmpattr
=
acap_attribute_new_simple
(
name
,
value
);
sinsert
(
sl
,
tmpattr
);
return
ACAP_OK
;
}
static
int
acapmbox_store
(
acapmbox_handle_t
*
AC
,
acapmbox_data_t
*
mboxdata
,
int
commit
)
{
int
result
;
acap_entry_t
*
newentry
;
acap_result_t
acapres
;
acap_cmd_t
*
cmd
;
char
*
fullname
;
char
tmpstr
[
30
];
if
(
AC
==
NULL
)
return
0
;
assert
(
mboxdata
);
if
(
AC
->
conn
==
NULL
)
{
return
IMAP_SERVER_UNAVAILABLE
;
}
/* create the new entry */
fullname
=
create_full_dataset_name
(
mboxdata
->
name
);
if
(
fullname
==
NULL
)
return
ACAP_NOMEM
;
newentry
=
acap_entry_new
(
fullname
);
if
(
newentry
==
NULL
)
return
ACAP_NOMEM
;
/* make and insert all our initial attributes */
snprintf
(
tmpstr
,
sizeof
(
tmpstr
),
"%d"
,
mboxdata
->
uidvalidity
);
add_attr
(
newentry
->
attrs
,
"mailbox.uidvalidity"
,
tmpstr
);
add_attr
(
newentry
->
attrs
,
"mailbox.status"
,
commit
?
"committed"
:
"reserved"
);
add_attr
(
newentry
->
attrs
,
"mailbox.post"
,
mboxdata
->
post
);
add_attr
(
newentry
->
attrs
,
"mailbox.haschildren"
,
mboxdata
->
haschildren
?
"yes"
:
"no"
);
add_attr
(
newentry
->
attrs
,
"mailbox.url"
,
mboxdata
->
url
);
add_attr
(
newentry
->
attrs
,
"mailbox.acl"
,
mboxdata
->
acl
);
snprintf
(
tmpstr
,
sizeof
(
tmpstr
),
"%d"
,
mboxdata
->
answered
);
add_attr
(
newentry
->
attrs
,
"mailbox.answered"
,
tmpstr
);
snprintf
(
tmpstr
,
sizeof
(
tmpstr
),
"%d"
,
mboxdata
->
flagged
);
add_attr
(
newentry
->
attrs
,
"mailbox.flagged"
,
tmpstr
);
snprintf
(
tmpstr
,
sizeof
(
tmpstr
),
"%d"
,
mboxdata
->
deleted
);
add_attr
(
newentry
->
attrs
,
"mailbox.deleted"
,
tmpstr
);
snprintf
(
tmpstr
,
sizeof
(
tmpstr
),
"%d"
,
mboxdata
->
total
);
add_attr
(
newentry
->
attrs
,
"mailbox.total"
,
tmpstr
);
/* create the cmd; if it's the first time through, we ACAP_STORE_INITIAL */
result
=
acap_store_entry
(
AC
->
conn
,
newentry
,
NULL
,
NULL
,
commit
?
0
:
ACAP_STORE_INITIAL
,
&
cmd
);
if
(
result
==
ACAP_OK
)
{
result
=
acap_process_on_command
(
AC
->
conn
,
cmd
,
&
acapres
);
if
(
acapres
!=
ACAP_RESULT_OK
)
{
/* this is a likely but not certain error */
result
=
IMAP_MAILBOX_EXISTS
;
}
}
/* xxx free memory */
return
result
;
}
int
acapmbox_create
(
acapmbox_handle_t
*
AC
,
acapmbox_data_t
*
mboxdata
)
{
return
acapmbox_store
(
AC
,
mboxdata
,
0
);
}
int
acapmbox_markactive
(
acapmbox_handle_t
*
AC
,
acapmbox_data_t
*
mboxdata
)
{
return
acapmbox_store
(
AC
,
mboxdata
,
1
);
}
static
void
myacap_entry
(
acap_entry_t
*
entry
,
void
*
rock
)
{
int
*
num
=
(
int
*
)
rock
;
skipnode
*
node
;
acap_attribute_t
*
attr
;
printf
(
"
\t
entry = %s
\n
"
,
entry
->
name
);
attr
=
sfirst
(
entry
->
attrs
,
&
node
);
while
(
attr
)
{
printf
(
"
\t\t
%s = %s
\n
"
,
attr
->
name
,
attr
->
v
->
data
);
attr
=
snext
(
&
node
);
}
/* indicate we saw something */
*
num
=
1
;
}
static
void
myacap_modtime
(
char
*
modtime
,
void
*
rock
)
{
printf
(
"
\t
modtime = %s
\n
"
,
modtime
);
}
static
struct
acap_search_callback
myacap_search_cb
=
{
&
myacap_entry
,
&
myacap_modtime
};
static
struct
acap_requested
myacap_request
=
{
1
,
{
"entry"
}
};
/*
* Returns:
* ACAP_OK -> does exist
* ACAP_FAIL -> doesn't exist
* other -> error
*
*/
int
acapmbox_entryexists
(
acapmbox_handle_t
*
AC
,
char
*
mailbox_name
)
{
acap_cmd_t
*
cmd
;
int
r
;
char
*
search_crit
;
int
exists
=
0
;
if
(
AC
==
NULL
)
return
0
;
assert
(
mailbox_name
!=
NULL
);
if
(
AC
->
conn
==
NULL
)
{
return
IMAP_SERVER_UNAVAILABLE
;
}
/* create search criteria */
search_crit
=
(
char
*
)
malloc
(
strlen
(
mailbox_name
)
+
30
);
if
(
search_crit
==
NULL
)
return
ACAP_NOMEM
;
sprintf
(
search_crit
,
"EQUAL
\"
entry
\"
\"
i;octet
\"
\"
%s
\"
"
,
mailbox_name
);
r
=
acap_search_dataset
(
AC
->
conn
,
global_dataset
,
search_crit
,
1
,
&
myacap_request
,
NULL
,
NULL
,
&
myacap_search_cb
,
NULL
,
NULL
,
&
exists
,
&
cmd
);
if
(
r
!=
ACAP_OK
)
{
return
r
;
}
r
=
acap_process_on_command
(
AC
->
conn
,
cmd
,
NULL
);
if
(
r
!=
ACAP_OK
)
{
return
r
;
}
return
(
exists
==
0
)
?
ACAP_FAIL
:
ACAP_OK
;
}
int
acapmbox_setproperty
(
acapmbox_handle_t
*
AC
,
char
*
mailbox_name
,
acapmbox_property_t
prop
,
int
value
)
{
int
result
;
char
*
fullname
;
acap_cmd_t
*
cmd
;
acap_attribute_t
*
tmpattr
;
char
*
attrname
;
char
attrvalue
[
30
];
if
(
AC
==
NULL
)
return
0
;
assert
(
mailbox_name
!=
NULL
);
if
(
AC
->
conn
==
NULL
)
{
return
IMAP_SERVER_UNAVAILABLE
;
}
/* get the entry path */
fullname
=
create_full_dataset_name
(
mailbox_name
);
if
(
fullname
==
NULL
)
return
ACAP_NOMEM
;
/* create the attribute */
switch
(
prop
)
{
case
ACAPMBOX_ANSWERED
:
attrname
=
"mailbox.answered"
;
break
;
case
ACAPMBOX_FLAGGED
:
attrname
=
"mailbox.flagged"
;
break
;
case
ACAPMBOX_DELETED
:
attrname
=
"mailbox.deleted"
;
break
;
case
ACAPMBOX_TOTAL
:
attrname
=
"mailbox.total"
;
break
;
default
:
return
ACAP_BAD_PARAM
;
break
;
}
snprintf
(
attrvalue
,
sizeof
(
attrvalue
),
"%d"
,
value
);
tmpattr
=
acap_attribute_new_simple
(
attrname
,
attrvalue
);
if
(
tmpattr
==
NULL
)
return
ACAP_NOMEM
;
/* issue store command */
result
=
acap_store_attribute
(
AC
->
conn
,
fullname
,
tmpattr
,
NULL
,
/* don't care about unchangedsince */
NULL
,
NULL
,
&
cmd
);
/* get result of command */
result
=
acap_process_on_command
(
AC
->
conn
,
cmd
,
NULL
);
if
(
result
!=
ACAP_OK
)
{
printf
(
"failure on command
\n
"
);
}
/* xxx free memory */
return
result
;
}
int
acapmbox_setproperty_acl
(
acapmbox_handle_t
*
AC
,
char
*
mailbox_name
,
char
*
newvalue
)
{
int
result
;
char
*
fullname
;
acap_cmd_t
*
cmd
;
acap_attribute_t
*
tmpattr
;
char
*
attrname
;
char
attrvalue
[
30
];
if
(
AC
==
NULL
)
return
0
;
assert
(
mailbox_name
!=
NULL
);
if
(
AC
->
conn
==
NULL
)
{
return
IMAP_SERVER_UNAVAILABLE
;
}
/* get the entry path */
fullname
=
create_full_dataset_name
(
mailbox_name
);
if
(
fullname
==
NULL
)
return
ACAP_NOMEM
;
/* create the attribute */
attrname
=
"mailbox.acl"
;
tmpattr
=
acap_attribute_new_simple
(
attrname
,
newvalue
);
if
(
tmpattr
==
NULL
)
return
ACAP_NOMEM
;
/* issue store command */
result
=
acap_store_attribute
(
AC
->
conn
,
fullname
,
tmpattr
,
NULL
,
/* don't care about unchangedsince */
NULL
,
NULL
,
&
cmd
);
/* get result of command */
result
=
acap_process_on_command
(
AC
->
conn
,
cmd
,
NULL
);
if
(
result
!=
ACAP_OK
)
{
printf
(
"failure on command
\n
"
);
}
/* xxx free memory */
return
result
;
}
acapmbox_status
mboxdata_convert_status
(
acap_value_t
*
v
)
{
char
*
s
=
v
->
data
;
if
(
!
s
||
v
->
next
)
return
ACAPMBOX_UNKNOWN
;
if
(
s
&&
(
*
s
==
'c'
||
*
s
==
'C'
))
return
ACAPMBOX_COMMITTED
;
else
if
(
s
&&
(
*
s
==
'r'
||
*
s
==
'R'
))
return
ACAPMBOX_RESERVED
;
else
return
ACAPMBOX_UNKNOWN
;
}
static
void
myacap_copy_entry
(
acap_entry_t
*
entry
,
void
*
rock
)
{
acapmbox_data_t
*
mboxdata
=
(
acapmbox_data_t
*
)
rock
;
skipnode
*
node
;
acap_attribute_t
*
attr
;
printf
(
"
\t
entry = %s
\n
"
,
entry
->
name
);
attr
=
sfirst
(
entry
->
attrs
,
&
node
);
while
(
attr
)
{
printf
(
"
\t\t
%s = %s
\n
"
,
attr
->
name
,
attr
->
v
->
data
);
if
(
strcmp
(
attr
->
name
,
"mailbox.status"
)
==
0
)
{
mboxdata
->
status
=
mboxdata_convert_status
(
attr
->
v
);
}
else
if
(
strcmp
(
attr
->
name
,
"mailbox.total"
)
==
0
)
{
mboxdata
->
total
=
atoi
(
attr
->
v
->
data
);
}
attr
=
snext
(
&
node
);
}
}
static
void
myacap_copy_modtime
(
char
*
modtime
,
void
*
rock
)
{
printf
(
"
\t
modtime = %s
\n
"
,
modtime
);
}
static
struct
acap_search_callback
myacap_search_copy_cb
=
{
&
myacap_copy_entry
,
&
myacap_copy_modtime
};
static
struct
acap_requested
myacap_copy_request
=
{
1
,
{
"*"
}
};
int
acapmbox_delete
(
acapmbox_handle_t
*
AC
,
char
*
mailbox_name
)
{
acap_cmd_t
*
cmd
;
int
r
;
char
*
fullname
;
if
(
AC
==
NULL
)
return
0
;
assert
(
mailbox_name
!=
NULL
);
if
(
AC
->
conn
==
NULL
)
{
return
IMAP_SERVER_UNAVAILABLE
;
}
/* create the new entry */
fullname
=
create_full_dataset_name
(
mailbox_name
);
if
(
fullname
==
NULL
)
return
ACAP_NOMEM
;
r
=
acap_delete_entry_name
(
AC
->
conn
,
fullname
,
NULL
,
NULL
,
&
cmd
);
if
(
!
r
)
r
=
acap_process_on_command
(
AC
->
conn
,
cmd
,
NULL
);
return
r
;
}
int
acapmbox_deleteall
(
acapmbox_handle_t
*
AC
)
{
acap_cmd_t
*
cmd
;
int
r
;
if
(
AC
==
NULL
)
return
ACAP_OK
;
r
=
acap_delete_entry_name
(
AC
->
conn
,
global_dataset
,
NULL
,
NULL
,
&
cmd
);
if
(
!
r
)
r
=
acap_process_on_command
(
AC
->
conn
,
cmd
,
NULL
);
return
r
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Apr 24, 2:29 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18868852
Default Alt Text
acapmbox.c (11 KB)
Attached To
Mode
R111 cyrus-imapd
Attached
Detach File
Event Timeline