Added mmbox handler module, fixes to message coder/decoder.
This commit is contained in:
parent
eacef28de6
commit
f9a34a1aea
|
@ -1,5 +1,5 @@
|
|||
noinst_LIBRARIES = libmms.a
|
||||
libmms_a_SOURCES = mms_billing.c mms_billing.h mms_msg.c mms_msg.h mms_queue.c mms_queue.h mms_strings.c mms_strings.h mms_uaprof.c mms_uaprof.h mms_util.c mms_util.h mms_resolve.c
|
||||
libmms_a_SOURCES = mms_mmbox.h mms_mmbox.c mms_billing.c mms_billing.h mms_msg.c mms_msg.h mms_queue.c mms_queue.h mms_strings.c mms_strings.h mms_uaprof.c mms_uaprof.h mms_util.c mms_util.h mms_resolve.c
|
||||
|
||||
plugindir = $(libdir)/mbuni
|
||||
plugin_LTLIBRARIES = libmms_billing_shell.la libmms_resolve_shell.la libmms_detokenize_shell.la
|
||||
|
|
|
@ -0,0 +1,735 @@
|
|||
/*
|
||||
* MMS MMBox management module - P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
*/
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mms_mmbox.h"
|
||||
#include "mms_util.h"
|
||||
#include "gwlib/log.h"
|
||||
#include "gwlib/accesslog.h"
|
||||
|
||||
#define MAXTRIES 10
|
||||
#define MDF 'd'
|
||||
#define MTF 't'
|
||||
#define IDXFILE "00Index"
|
||||
|
||||
#define ITEM_ADD 1
|
||||
#define ITEM_DEL 2
|
||||
#define ITEM_MOD 3
|
||||
|
||||
#define _TT "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
#define _TTSIZE (-1 + sizeof _TT)
|
||||
|
||||
static unsigned long hash(char *s)
|
||||
{
|
||||
unsigned h = 0;
|
||||
|
||||
while (*s) {
|
||||
unsigned int ch = tolower(*s);
|
||||
s++;
|
||||
h += ((unsigned)(ch) << 4) + 1249;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
/* Initialise the root of the mmbox. Should be called once from load settings. */
|
||||
int mmbox_root_init(char *mmbox_root)
|
||||
{
|
||||
int i, ret;
|
||||
if ((ret = mkdir(mmbox_root,
|
||||
S_IRWXU|S_IRWXG)) < 0 &&
|
||||
errno != EEXIST)
|
||||
return errno;
|
||||
for (i = 0; _TT[i]; i++) {
|
||||
char fbuf[256];
|
||||
|
||||
sprintf(fbuf, "%.128s/%c", mmbox_root, _TT[i]);
|
||||
if (mkdir(fbuf,
|
||||
S_IRWXU|S_IRWXG) < 0 &&
|
||||
errno != EEXIST)
|
||||
return errno;
|
||||
}
|
||||
srandom(time(NULL)); /* we need rands below...*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialise the mmbox home of the user/msisdn.
|
||||
* structure of mmbox is:
|
||||
* - index file [IDXFILE]
|
||||
* - directories a - z 0 - 9, which each can contain directories with two-character
|
||||
* names
|
||||
* on init we only create the directory itself. internal
|
||||
* directory structure and index will be made by first message put in.
|
||||
* return user dir, or NULL if something went wrong.
|
||||
*/
|
||||
static Octstr *user_mmbox_dir(char *mmbox_root, char *userid)
|
||||
{
|
||||
|
||||
unsigned long h = hash(userid);
|
||||
char d1[2], d2[3], fbuf[512];
|
||||
Octstr *t, *s;
|
||||
|
||||
/* Make toplevel dir. */
|
||||
d1[0] = _TT[h%_TTSIZE];
|
||||
d1[1] = '\0';
|
||||
|
||||
/* Then lower level. */
|
||||
h /= _TTSIZE;
|
||||
d2[0] = _TT[h%_TTSIZE];
|
||||
h /= _TTSIZE;
|
||||
d2[1] = _TT[h%_TTSIZE];
|
||||
d2[2] = '\0';
|
||||
|
||||
/* Try and create the next level dir (first level was created by root_init) */
|
||||
sprintf(fbuf, "%.128s/%s/%s", mmbox_root, d1, d2);
|
||||
if (mkdir(fbuf,
|
||||
S_IRWXU|S_IRWXG) < 0 &&
|
||||
errno != EEXIST) {
|
||||
error(0, "mmbox: failed to create dir [%s] "
|
||||
"while initialising mmbox for %s: %s!",
|
||||
fbuf, userid, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t = octstr_create(userid);
|
||||
octstr_replace(t, octstr_imm("/"), octstr_imm("$")); /* XXX safe in all cases?? */
|
||||
s = octstr_format("%s/%S", fbuf, t);
|
||||
octstr_destroy(t);
|
||||
|
||||
if (mkdir(octstr_get_cstr(s),
|
||||
S_IRWXU|S_IRWXG) < 0 &&
|
||||
errno != EEXIST) {
|
||||
error(0, "mmbox: failed to create dir [%s] "
|
||||
"while initialising mmbox for %s: %s!",
|
||||
octstr_get_cstr(s), userid, strerror(errno));
|
||||
octstr_destroy(s);
|
||||
return NULL;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Makes a file name in the nested directory structure, where we can store
|
||||
* data. Makes a number of tries -- similar to mkqf in queue module.
|
||||
*/
|
||||
static int mkdf(char df[64], char *mmbox_home)
|
||||
{
|
||||
|
||||
int i = 0, fd = -1;
|
||||
static int ect;
|
||||
|
||||
if (!mmbox_home)
|
||||
gw_panic(0, "Mmbox directory passed as null!");
|
||||
|
||||
do {
|
||||
char d1[2], d2[3];
|
||||
Octstr *tmp;
|
||||
char *ctmp;
|
||||
|
||||
d1[0] = _TT[random() % _TTSIZE];
|
||||
d1[1] = '\0';
|
||||
|
||||
/* Make first level. */
|
||||
tmp = octstr_format("%.128s/%s", mmbox_home, d1);
|
||||
if (mkdir(octstr_get_cstr(tmp),
|
||||
S_IRWXU|S_IRWXG) < 0 &&
|
||||
errno != EEXIST) {
|
||||
error(0, "mmbox.mkdf: failed to create dir [%s] "
|
||||
" in mmbox home %s: %s!",
|
||||
octstr_get_cstr(tmp), mmbox_home, strerror(errno));
|
||||
octstr_destroy(tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
octstr_destroy(tmp);
|
||||
|
||||
d2[0] = _TT[random() % _TTSIZE];
|
||||
d2[1] = _TT[random() % _TTSIZE];
|
||||
d2[2] = '\0';
|
||||
|
||||
/* Make second level. */
|
||||
tmp = octstr_format("%.128s/%s/%s", mmbox_home, d1,d2);
|
||||
|
||||
if (mkdir(octstr_get_cstr(tmp),
|
||||
S_IRWXU|S_IRWXG) < 0 &&
|
||||
errno != EEXIST) {
|
||||
error(0, "mmbox.mkdf: failed to create dir [%s] "
|
||||
" in mmbox home %s: %s!",
|
||||
octstr_get_cstr(tmp), mmbox_home, strerror(errno));
|
||||
octstr_destroy(tmp);
|
||||
return -1;
|
||||
}
|
||||
octstr_destroy(tmp);
|
||||
|
||||
/* use df[] to store candidate so when we hit success it is already there...*/
|
||||
sprintf(df, "%s/%s/%cf%ld.%d.x%d%ld",
|
||||
d1,d2, MDF,
|
||||
time(NULL),
|
||||
++ect, getpid(), random() % 100);
|
||||
tmp = octstr_format("%s/%s", mmbox_home, df);
|
||||
ctmp = octstr_get_cstr(tmp);
|
||||
fd = open(ctmp, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
|
||||
if (fd >= 0 &&
|
||||
mm_lockfile(fd,ctmp,1) != 0) {
|
||||
unlink(ctmp);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
octstr_destroy(tmp);
|
||||
|
||||
} while (i++ < MAXTRIES && fd < 0);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int open_mmbox_index(char *mmbox_dir, int shouldblock)
|
||||
{
|
||||
char fbuf[256];
|
||||
int i, fd;
|
||||
|
||||
sprintf(fbuf, "%s/%s", mmbox_dir, IDXFILE);
|
||||
|
||||
i = 0;
|
||||
do
|
||||
if ((fd = open(fbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)) < 0) {
|
||||
error(0, "Failed to open mmbox index file [%s], error: %s!",
|
||||
fbuf, strerror(errno));
|
||||
break;
|
||||
} else if (mm_lockfile(fd, fbuf, shouldblock) != 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
while (i++ < MAXTRIES && fd < 0);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static Octstr *linearise_string_list(List *l, char *sep)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
Octstr *s = octstr_create("");
|
||||
|
||||
for (i = 0, n = list_len(l); i < n; i++) {
|
||||
Octstr *p = list_get(l,i);
|
||||
if (p)
|
||||
octstr_format_append(s, "%s%S", (i == 0) ? "" : sep, p);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static List *parse_string_list(char *buf)
|
||||
{
|
||||
int i = 0;
|
||||
char sbuf[128], *p = buf;
|
||||
List *l = list_create();
|
||||
|
||||
while (sscanf(p, "%s%n", sbuf, &i) > 0) {
|
||||
list_append(l, octstr_create(sbuf));
|
||||
p += i;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static char *skip_space(char *s)
|
||||
{
|
||||
while (*s && isspace(*s))
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Format of Index file:
|
||||
* each message is described by a single line:
|
||||
* df state flag1 flag2 flag3 ...
|
||||
*/
|
||||
static int update_mmbox_index(int fd, char *mmbox_dir, int cmd,
|
||||
Octstr *df, Octstr *state, List *flags)
|
||||
{
|
||||
char fbuf[256], linbuf[1024];
|
||||
int tempfd;
|
||||
FILE *fp;
|
||||
|
||||
/* Make a temp file. */
|
||||
|
||||
sprintf(fbuf, "%.128s/t%s.%ld.%ld",
|
||||
mmbox_dir, IDXFILE, time(NULL), random() % 1000);
|
||||
|
||||
tempfd = open(fbuf,
|
||||
O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
|
||||
if (tempfd < 0 ) {
|
||||
error(0, "mmbox.update_index: Failed to open temp file %s: error = %s\n",
|
||||
fbuf, strerror(errno));
|
||||
|
||||
goto done;
|
||||
} else if (mm_lockfile(tempfd, fbuf, 0) != 0) { /* Lock it. */
|
||||
error(0, "mmbox.update_index: Failed lock temp file %s: error = %s\n",
|
||||
fbuf, strerror(errno));
|
||||
|
||||
close(tempfd);
|
||||
tempfd = -1;
|
||||
goto done;
|
||||
|
||||
}
|
||||
fp = fdopen(fd, "r");
|
||||
|
||||
if (!fp) {
|
||||
error(0, "mmbox.update_index: Failed fdopen on tempfd, file %s: error = %s\n",
|
||||
|
||||
fbuf, strerror(errno));
|
||||
|
||||
close(tempfd);
|
||||
tempfd = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
|
||||
char idx[128], xstate[32];
|
||||
Octstr *outs = NULL;
|
||||
int i;
|
||||
|
||||
sscanf(linbuf, "%s %s%n", idx, xstate, &i);
|
||||
|
||||
if (df && octstr_str_compare(df, idx) == 0)
|
||||
if (cmd == ITEM_DEL || cmd == ITEM_ADD)
|
||||
goto loop; /* Skip it. */
|
||||
else { /* MOD. */
|
||||
Octstr *p = linearise_string_list(flags, " ");
|
||||
outs = octstr_format("%S %S %S\n", df, state, p);
|
||||
octstr_destroy(p);
|
||||
}
|
||||
else { /* Copy out as-is */
|
||||
outs = octstr_format("%s %s %s%s",
|
||||
idx, xstate,
|
||||
skip_space(linbuf + i),
|
||||
(strchr(linbuf+i, '\n') >= 0 ? "" : "\n"));
|
||||
}
|
||||
loop:
|
||||
if (outs) {
|
||||
if (octstr_len(outs) > 0)
|
||||
octstr_write_to_socket(tempfd, outs);
|
||||
octstr_destroy(outs);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == ITEM_ADD) { /* Finally, for ADD, just add it. */
|
||||
Octstr *s, *p = linearise_string_list(flags, " ");
|
||||
s = octstr_format("%S %S %S\n", df, state, p);
|
||||
octstr_destroy(p);
|
||||
octstr_write_to_socket(tempfd, s);
|
||||
octstr_destroy(s);
|
||||
}
|
||||
fsync(tempfd);
|
||||
|
||||
sprintf(linbuf, "%.128s/%s",
|
||||
mmbox_dir, IDXFILE);
|
||||
rename(fbuf, linbuf);
|
||||
|
||||
fclose(fp);
|
||||
done:
|
||||
|
||||
return tempfd;
|
||||
}
|
||||
|
||||
static List *make_mm_flags(List *oflags, List *flag_cmds)
|
||||
{
|
||||
List *l = oflags ? oflags : list_create();
|
||||
int i, n;
|
||||
|
||||
for (i = 0, n = list_len(l); i < n; i++) { /* cleanup list. */
|
||||
Octstr *x = list_get(l,i);
|
||||
int ch = octstr_get_char(x, 0);
|
||||
|
||||
if (ch == '+' || ch == '-' || ch == '/')
|
||||
octstr_delete(x,0,1);
|
||||
}
|
||||
|
||||
for (i = 0, n = (flag_cmds ? list_len(flag_cmds) : 0); i<n; i++) {
|
||||
Octstr *x = list_get(flag_cmds,i);
|
||||
int ch = octstr_get_char(x, 0);
|
||||
char *s = octstr_get_cstr(x);
|
||||
int j, m, cmd;
|
||||
|
||||
if (ch == '+' || ch == '-' || ch == '/') {
|
||||
s++;
|
||||
cmd = ch;
|
||||
} else
|
||||
cmd = '+';
|
||||
|
||||
/* Find it in original. If existent, remove it. */
|
||||
for (j = 0, m = list_len(l); j < m; j++)
|
||||
if (octstr_str_compare(list_get(l,j),s) == 0) {
|
||||
Octstr *y = list_get(l,j);
|
||||
list_delete(l,j,1);
|
||||
octstr_destroy(y);
|
||||
j--;
|
||||
m--;
|
||||
}
|
||||
|
||||
if (cmd == '+' || cmd == '/')
|
||||
list_append(l, octstr_create(s));
|
||||
}
|
||||
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, Octstr *dfltstate)
|
||||
{
|
||||
int ifd = -1, nifd, dfd = -1;
|
||||
char df[128];
|
||||
Octstr *home = user_mmbox_dir(mmbox_root,user);
|
||||
Octstr *s = octstr_create(""), *sdf = NULL;
|
||||
List *flag_cmds = NULL, *flags = NULL;
|
||||
Octstr *state = NULL;
|
||||
|
||||
if (!home)
|
||||
goto done;
|
||||
ifd = open_mmbox_index(octstr_get_cstr(home),1);
|
||||
|
||||
if (ifd < 0)
|
||||
goto done;
|
||||
|
||||
if ((dfd = mkdf(df, octstr_get_cstr(home))) < 0) {
|
||||
error(0, "mmbox_add: failed to create data file, home=%s - %s!",
|
||||
octstr_get_cstr(home), strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
state = mms_get_header_value(msg, octstr_imm("X-Mms-MM-State"));
|
||||
flag_cmds = mms_get_header_values(msg, octstr_imm("X-Mms-MM-Flags"));
|
||||
|
||||
if (state == NULL)
|
||||
state = dfltstate ? octstr_duplicate(dfltstate) : octstr_create("Sent");
|
||||
flags = make_mm_flags(NULL, flag_cmds);
|
||||
|
||||
mms_replace_header_values(msg, "X-Mms-MM-Flags", flags);
|
||||
mms_replace_header_value(msg, "X-Mms-MM-State", octstr_get_cstr(state));
|
||||
|
||||
s = mms_tobinary(msg);
|
||||
octstr_write_to_socket(dfd, s);
|
||||
sdf = octstr_create(df);
|
||||
|
||||
if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_ADD, sdf, state, flags)) < 0 ) {
|
||||
char fbuf[256];
|
||||
sprintf(fbuf, "%s/%s", octstr_get_cstr(home), df);
|
||||
unlink(fbuf);
|
||||
octstr_destroy(sdf);
|
||||
sdf = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ifd = nifd;
|
||||
octstr_replace(sdf, octstr_imm("/"), octstr_imm("-"));
|
||||
done:
|
||||
if (dfd > 0)
|
||||
close(dfd);
|
||||
if (ifd > 0)
|
||||
close(ifd);
|
||||
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
if (home)
|
||||
octstr_destroy(home);
|
||||
if (state)
|
||||
octstr_destroy(state);
|
||||
if (flags)
|
||||
list_destroy(flags, (list_item_destructor_t *)octstr_destroy);
|
||||
if (flag_cmds)
|
||||
list_destroy(flag_cmds, (list_item_destructor_t *)octstr_destroy);
|
||||
|
||||
return sdf;
|
||||
}
|
||||
|
||||
int mms_mmbox_modmsg(char *mmbox_root, char *user, Octstr *msgref,
|
||||
Octstr *state, List *flag_cmds)
|
||||
{
|
||||
Octstr *sdf = octstr_duplicate(msgref);
|
||||
Octstr *fname = NULL, *ftmp = NULL;
|
||||
Octstr *home = user_mmbox_dir(mmbox_root,user);
|
||||
Octstr *s = NULL;
|
||||
List *flags = NULL;
|
||||
Octstr *nstate = NULL;
|
||||
|
||||
int ifd = -1, nifd, tmpfd = -1;
|
||||
MmsMsg *m = NULL;
|
||||
int res = -1;
|
||||
|
||||
octstr_replace(sdf, octstr_imm("-"), octstr_imm("/"));
|
||||
|
||||
if (!home)
|
||||
goto done;
|
||||
|
||||
ifd = open_mmbox_index(octstr_get_cstr(home),1);
|
||||
|
||||
if (ifd < 0)
|
||||
goto done;
|
||||
|
||||
fname = octstr_format("%S/%S", home, sdf);
|
||||
s = octstr_read_file(octstr_get_cstr(fname));
|
||||
|
||||
if ( s == NULL || octstr_len(s) == 0) {
|
||||
error(0, "mmbox.mod: failed to read data file [%s] - %s!",
|
||||
octstr_get_cstr(fname), strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
m = mms_frombinary(s, octstr_imm("anon@anon"));
|
||||
|
||||
if (!m) {
|
||||
error(0, "mmbox.mod: failed to read data file [%s]!",
|
||||
octstr_get_cstr(fname));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (state == NULL)
|
||||
nstate = mms_get_header_value(m, octstr_imm("X-Mms-MM-State"));
|
||||
else {
|
||||
nstate = octstr_duplicate(state);
|
||||
mms_replace_header_value(m, "X-Mms-MM-State", octstr_get_cstr(nstate));
|
||||
}
|
||||
|
||||
flags = mms_get_header_values(m, octstr_imm("X-Mms-MM-Flags"));
|
||||
flags = make_mm_flags(flags, flag_cmds);
|
||||
mms_replace_header_values(m, "X-Mms-MM-Flags", flags);
|
||||
|
||||
|
||||
ftmp = octstr_format("%S.%ld.%d", fname, time(NULL), getpid());
|
||||
tmpfd = open(octstr_get_cstr(ftmp), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
|
||||
|
||||
if (tmpfd < 0)
|
||||
goto done;
|
||||
|
||||
s = mms_tobinary(m);
|
||||
|
||||
octstr_write_to_socket(tmpfd, s);
|
||||
|
||||
rename(octstr_get_cstr(ftmp), octstr_get_cstr(fname));
|
||||
close(tmpfd);
|
||||
|
||||
if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_MOD, sdf, nstate, flags)) < 0) {
|
||||
/* Not good, we wrote but could not update the index file. scream. */
|
||||
error(0, "mmbox.mod: failed to update index file, home is %s!",
|
||||
octstr_get_cstr(home));
|
||||
goto done;
|
||||
}
|
||||
ifd = nifd;
|
||||
res = 0;
|
||||
|
||||
done:
|
||||
if (ifd > 0)
|
||||
close(ifd);
|
||||
|
||||
if (fname)
|
||||
octstr_destroy(fname);
|
||||
|
||||
if (ftmp)
|
||||
octstr_destroy(ftmp);
|
||||
|
||||
if (sdf)
|
||||
octstr_destroy(sdf);
|
||||
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
if (home)
|
||||
octstr_destroy(home);
|
||||
if (nstate)
|
||||
octstr_destroy(nstate);
|
||||
if (flags)
|
||||
list_destroy(flags, (list_item_destructor_t *)octstr_destroy);
|
||||
if (m)
|
||||
mms_destroy(m);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int mms_mmbox_delmsg(char *mmbox_root, char *user, Octstr *msgref)
|
||||
{
|
||||
|
||||
Octstr *sdf = octstr_duplicate(msgref);
|
||||
Octstr *fname = NULL, *home = user_mmbox_dir(mmbox_root,user);
|
||||
Octstr *s = NULL;
|
||||
int res = -1;
|
||||
int ifd = -1, nifd;
|
||||
|
||||
|
||||
octstr_replace(sdf, octstr_imm("-"), octstr_imm("/"));
|
||||
|
||||
if (!home)
|
||||
goto done;
|
||||
|
||||
ifd = open_mmbox_index(octstr_get_cstr(home),1);
|
||||
|
||||
if (ifd < 0)
|
||||
goto done;
|
||||
|
||||
fname = octstr_format("%S/%S", home, sdf);
|
||||
|
||||
if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_DEL, sdf, NULL, NULL)) < 0) {
|
||||
|
||||
error(0, "mmbox.del: failed to update index file, home is %s!",
|
||||
octstr_get_cstr(home));
|
||||
goto done;
|
||||
}
|
||||
unlink(octstr_get_cstr(fname));
|
||||
ifd = nifd;
|
||||
|
||||
res = 0;
|
||||
done:
|
||||
if (ifd > 0)
|
||||
close(ifd);
|
||||
|
||||
if (fname)
|
||||
octstr_destroy(fname);
|
||||
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
if (home)
|
||||
octstr_destroy(home);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int string_in_list(Octstr *s, List *l)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
for (i = 0, n = list_len(l); i<n; i++) {
|
||||
Octstr *x = list_get(l,i);
|
||||
char *p = octstr_get_cstr(x);
|
||||
|
||||
if (p[0] == '+' ||
|
||||
p[0] == '/' || p[0] == '-')
|
||||
p++;
|
||||
if (octstr_str_compare(s, p) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _x_octstr_str_compare(Octstr *s, char *p)
|
||||
{
|
||||
return (octstr_str_compare(s,p) == 0);
|
||||
}
|
||||
List *mms_mmbox_search(char *mmbox_root, char *user,
|
||||
List *state, List *flag_cmds, int start, int limit)
|
||||
{
|
||||
int tmpfd = -1;
|
||||
FILE *fp = NULL;
|
||||
char linbuf[1024];
|
||||
|
||||
Octstr *home = user_mmbox_dir(mmbox_root,user);
|
||||
List *flags = NULL;
|
||||
List *dflist = NULL;
|
||||
|
||||
int ifd = -1;
|
||||
int ct;
|
||||
|
||||
ifd = open_mmbox_index(octstr_get_cstr(home),1);
|
||||
|
||||
if (ifd < 0)
|
||||
goto done;
|
||||
|
||||
if ((tmpfd = dup(ifd)) < 0 ||
|
||||
(fp = fdopen(tmpfd, "r")) == NULL) {
|
||||
error(0, "mmbox.search_index: %s Failed to dup descriptor for index "
|
||||
"file, fp = %d: error = %s\n", octstr_get_cstr(home),
|
||||
(int)fp, strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
flags = make_mm_flags(NULL, flag_cmds);
|
||||
|
||||
ct = 1;
|
||||
dflist = list_create();
|
||||
while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
|
||||
char idx[128], xstate[32];
|
||||
List *xflags = NULL;
|
||||
int i;
|
||||
|
||||
sscanf(linbuf, "%s %s%n", idx, xstate, &i);
|
||||
|
||||
/* search. */
|
||||
if ((!state || list_search(state, xstate,
|
||||
(list_item_matches_t *)_x_octstr_str_compare) != NULL) &&
|
||||
(!flag_cmds || list_len(flag_cmds) == 0 ||
|
||||
((xflags = parse_string_list(linbuf + i)) != NULL &&
|
||||
list_search(xflags, flags, (list_item_matches_t *)string_in_list) != NULL)))
|
||||
if (ct >= start && ct <= limit) {
|
||||
Octstr *x = octstr_create(idx);
|
||||
octstr_replace(x, octstr_imm("/"), octstr_imm("-"));
|
||||
list_append(dflist, x);
|
||||
}
|
||||
ct++;
|
||||
if (xflags)
|
||||
list_destroy(xflags, (list_item_destructor_t *)octstr_destroy);
|
||||
}
|
||||
|
||||
done:
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
else if (tmpfd)
|
||||
close(tmpfd);
|
||||
|
||||
if (ifd > 0)
|
||||
close(ifd);
|
||||
|
||||
if (flags)
|
||||
list_destroy(flags, (list_item_destructor_t *)octstr_destroy);
|
||||
|
||||
if (home)
|
||||
octstr_destroy(home);
|
||||
|
||||
return dflist;
|
||||
}
|
||||
|
||||
MmsMsg *mms_mmbox_get(char *mmbox_root, char *user, Octstr *msgref)
|
||||
{
|
||||
Octstr *sdf = octstr_duplicate(msgref);
|
||||
Octstr *fname = NULL, *home = user_mmbox_dir(mmbox_root,user);
|
||||
Octstr *s = NULL;
|
||||
int ifd = -1;
|
||||
MmsMsg *m = NULL;
|
||||
|
||||
|
||||
octstr_replace(sdf, octstr_imm("-"), octstr_imm("/"));
|
||||
|
||||
if (!home)
|
||||
goto done;
|
||||
|
||||
ifd = open_mmbox_index(octstr_get_cstr(home),1); /* Grab a lock on the index file. */
|
||||
|
||||
if (ifd < 0)
|
||||
goto done;
|
||||
|
||||
fname = octstr_format("%S/%S", home, sdf);
|
||||
s = octstr_read_file(octstr_get_cstr(fname));
|
||||
|
||||
if (s)
|
||||
m = mms_frombinary(s, octstr_imm("anon@anon"));
|
||||
|
||||
done:
|
||||
if (ifd > 0)
|
||||
close(ifd);
|
||||
|
||||
if (fname)
|
||||
octstr_destroy(fname);
|
||||
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
if (home)
|
||||
octstr_destroy(home);
|
||||
|
||||
return m;
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef __MMS_MMBOX__INCLUDED__
|
||||
#define __MMS_MMBOX__INCLUDED__
|
||||
#include "mms_msg.h"
|
||||
/* Initialise the root of the mmbox. Should be called once from load settings. */
|
||||
int mmbox_root_init(char *mmbox_root);
|
||||
Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, Octstr *dfltstate);
|
||||
int mms_mmbox_modmsg(char *mmbox_root, char *user, Octstr *msgref,
|
||||
Octstr *state, List *flag_cmds);
|
||||
int mms_mmbox_delmsg(char *mmbox_root, char *user, Octstr *msgref);
|
||||
List *mms_mmbox_search(char *mmbox_root, char *user,
|
||||
List *state, List *flag_cmds, int start, int limit);
|
||||
|
||||
MmsMsg *mms_mmbox_get(char *mmbox_root, char *user, Octstr *msgref);
|
||||
#endif
|
|
@ -25,7 +25,7 @@ static void mm_destroy(MIMEEntity *mx);
|
|||
|
||||
static inline void pack_short_integer(Octstr *s, int ch)
|
||||
{
|
||||
unsigned long c = ch&0x7f;
|
||||
unsigned long c = ((unsigned)ch)&0x7f;
|
||||
wsp_pack_short_integer(s, c);
|
||||
}
|
||||
|
||||
|
@ -741,15 +741,15 @@ static void mms_pack_well_known_field(Octstr *os, int field_type, Octstr *value)
|
|||
int i = 1;
|
||||
ch = octstr_get_char(value, 0);
|
||||
|
||||
if (ch == '-')
|
||||
wsp_pack_short_integer(encoded, 0x81);
|
||||
if (ch == '+')
|
||||
pack_short_integer(encoded, 0x80);
|
||||
else if (ch == '-')
|
||||
pack_short_integer(encoded, 0x81);
|
||||
else if (ch == '/')
|
||||
wsp_pack_short_integer(encoded, 0x82);
|
||||
else if (ch == '+') /* Missing, or '+' ..*/
|
||||
wsp_pack_short_integer(encoded, 0x80);
|
||||
pack_short_integer(encoded, 0x82);
|
||||
else {
|
||||
i = 0;
|
||||
wsp_pack_short_integer(encoded, 0x80);
|
||||
pack_short_integer(encoded, 0x82); /* default is filter. */
|
||||
}
|
||||
s = octstr_copy(value, i, octstr_len(value));
|
||||
wsp_pack_text(encoded, s);
|
||||
|
@ -1502,6 +1502,18 @@ int mms_replace_header_value(MmsMsg *msg, char *hname, char *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mms_replace_header_values(MmsMsg *msg, char *hname, List *value)
|
||||
{
|
||||
int i;
|
||||
http_header_remove_all(msg->headers, hname);
|
||||
|
||||
for (i = 0; i < list_len(value); i++) {
|
||||
Octstr *x = list_get(value, i);
|
||||
http_header_add(msg->headers, hname, octstr_get_cstr(x));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Octstr *mms_get_header_value(MmsMsg *msg, Octstr *header)
|
||||
{
|
||||
|
||||
|
@ -1510,6 +1522,25 @@ Octstr *mms_get_header_value(MmsMsg *msg, Octstr *header)
|
|||
}
|
||||
|
||||
|
||||
List *mms_get_header_values(MmsMsg *msg, Octstr *header)
|
||||
{
|
||||
List *h = http_header_find_all(msg->headers, octstr_get_cstr(header));
|
||||
List *l = list_create();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < list_len(h); i++) {
|
||||
Octstr *hname, *value;
|
||||
|
||||
http_header_get(h, i, &hname, &value);
|
||||
|
||||
list_append(l, value);
|
||||
octstr_destroy(hname);
|
||||
}
|
||||
http_destroy_headers(h);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
int mms_convert_readrec2readorig(MmsMsg *msg)
|
||||
{
|
||||
if (msg->message_type != MMS_MSGTYPE_READ_REC_IND)
|
||||
|
|
|
@ -49,8 +49,14 @@ extern MmsMsg *mms_notification(MmsMsg *msg, unsigned int msize,
|
|||
MmsMsg *mms_retrieveconf(MmsMsg *msg, Octstr *transactionid, char *err, char *errtxt, Octstr *opt_from);
|
||||
int mms_remove_headers(MmsMsg *m, char *name);
|
||||
MmsMsg *mms_sendconf(char *errstr, char *msgid, char *transid, int isforward);
|
||||
|
||||
Octstr *mms_get_header_value(MmsMsg *msg, Octstr *header);
|
||||
|
||||
/* Returns a list of values for the header given. */
|
||||
List *mms_get_header_values(MmsMsg *msg, Octstr *header);
|
||||
|
||||
int mms_replace_header_value(MmsMsg *msg, char *hname, char *value);
|
||||
int mms_replace_header_values(MmsMsg *msg, char *hname, List *values);
|
||||
|
||||
int mms_convert_readrec2readorig(MmsMsg *msg);
|
||||
|
||||
|
|
|
@ -22,47 +22,6 @@
|
|||
|
||||
|
||||
static int free_envelope(MmsEnvelope *e, int removefromqueue);
|
||||
/*
|
||||
* lockfile: tries to lock a file, returns 0 if success, errno (which could be +ve) otherwise.
|
||||
* we use flock()
|
||||
*/
|
||||
static int lockfile(int fd, int shouldblock)
|
||||
{
|
||||
int n, stop;
|
||||
unsigned flg = shouldblock ? 0 : LOCK_NB;
|
||||
|
||||
do {
|
||||
n = flock(fd, LOCK_EX|flg);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
stop = 0;
|
||||
else
|
||||
stop = 1;
|
||||
} else
|
||||
stop = 1;
|
||||
} while (!stop);
|
||||
|
||||
return (n == 0) ? 0 : errno;
|
||||
}
|
||||
|
||||
static int check_lock(int fd, char *fname)
|
||||
{
|
||||
struct stat fs = {0}, ds = {0};
|
||||
|
||||
|
||||
if (fstat(fd, &ds) < 0 ||
|
||||
stat(fname, &fs) < 0 ||
|
||||
|
||||
ds.st_nlink != fs.st_nlink ||
|
||||
memcmp(&ds.st_dev,&fs.st_dev, sizeof ds.st_dev) != 0 ||
|
||||
memcmp(&ds.st_ino,&fs.st_ino, sizeof ds.st_ino) != 0 ||
|
||||
ds.st_uid != fs.st_uid ||
|
||||
ds.st_gid != fs.st_gid ||
|
||||
ds.st_size != fs.st_size)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/* Queue file structure:
|
||||
* - File consists of a series of lines, each line begins with a single letter, followed by
|
||||
* a parameter. Letters mean:
|
||||
|
@ -115,19 +74,15 @@ MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldbloc
|
|||
int okfile = 0;
|
||||
|
||||
fname = octstr_format( "%.128s/%s", mms_queuedir, qf);
|
||||
|
||||
|
||||
if ((fd = open(octstr_get_cstr(fname), O_RDONLY)) < 0) {
|
||||
octstr_destroy(fname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lockfile(fd, shouldblock) != 0 ||
|
||||
check_lock(fd, octstr_get_cstr(fname)) != 0) {
|
||||
} else if (mm_lockfile(fd, octstr_get_cstr(fname), shouldblock) != 0) {
|
||||
close(fd);
|
||||
octstr_destroy(fname);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
e = gw_malloc(sizeof *e);
|
||||
memset(e, 0, sizeof *e); /* Clear it all .*/
|
||||
|
@ -277,8 +232,7 @@ static int writeenvelope(MmsEnvelope *e, int newenv)
|
|||
|
||||
res = -1;
|
||||
goto done;
|
||||
} else if (lockfile(fd, 0) != 0 ||
|
||||
check_lock(fd, octstr_get_cstr(tfname)) != 0) { /* Lock it. */
|
||||
} else if (mm_lockfile(fd, octstr_get_cstr(tfname), 0) != 0) { /* Lock it. */
|
||||
error(0, "mms_queueadd: Failed lock temp file %s: error = %s\n",
|
||||
octstr_get_cstr(tfname), strerror(errno));
|
||||
res = -1;
|
||||
|
@ -423,8 +377,7 @@ static int mkqf(char qf[32], char *mms_queuedir)
|
|||
ctmp = octstr_get_cstr(tmp);
|
||||
fd = open(ctmp, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
|
||||
if (fd >= 0 &&
|
||||
(lockfile(fd,1) != 0 ||
|
||||
check_lock(fd, ctmp) != 0)) {
|
||||
mm_lockfile(fd,ctmp,1) != 0) {
|
||||
unlink(ctmp);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef _MMSQUEUE_INCLUDED__
|
||||
#define _MMSQUEUE_INCLUDED__
|
||||
#ifndef _MMS_QUEUE_INCLUDED__
|
||||
#define _MMS_QUEUE_INCLUDED__
|
||||
|
||||
#include "mms_msg.h"
|
||||
#include "mms_util.h"
|
||||
|
||||
#define QFNAMEMAX 32
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
#include <sys/file.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mms_util.h"
|
||||
#include "mms_uaprof.h"
|
||||
|
||||
|
@ -83,7 +90,8 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
m->global_queuedir = cfg_getx(grp, octstr_imm("send-queue-directory"));
|
||||
m->mm1_queuedir = cfg_getx(grp, octstr_imm("mm1-queue-directory"));
|
||||
m->mm4_queuedir = cfg_getx(grp, octstr_imm("mm4-queue-directory"));
|
||||
|
||||
m->mmbox_rootdir = cfg_getx(grp, octstr_imm("mmbox-root-directory"));
|
||||
|
||||
if (cfg_get_integer(&m->maxsendattempts, grp, octstr_imm("maximum-send-attempts")) == -1)
|
||||
m->maxsendattempts = MAXQTRIES;
|
||||
|
||||
|
@ -202,6 +210,10 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
|
||||
cfg_get_bool(&m->allow_ip_type, grp, octstr_imm("allow-ip-type"));
|
||||
cfg_get_bool(&m->optimize_notification_size, grp, octstr_imm("optimize-notification-size"));
|
||||
|
||||
if (mmbox_root_init(octstr_get_cstr(m->mmbox_rootdir)) != 0)
|
||||
warning(0, "Failed to initialise mmbox root directory, error: %s!",
|
||||
strerror(errno));
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -937,3 +949,53 @@ void mms_log(char *logmsg, Octstr *from, List *to,
|
|||
octstr_destroy(xto);
|
||||
}
|
||||
|
||||
|
||||
static int lockfile(int fd, int shouldblock)
|
||||
{
|
||||
int n, stop;
|
||||
unsigned flg = shouldblock ? 0 : LOCK_NB;
|
||||
|
||||
do {
|
||||
n = flock(fd, LOCK_EX|flg);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
stop = 0;
|
||||
else
|
||||
stop = 1;
|
||||
} else
|
||||
stop = 1;
|
||||
} while (!stop);
|
||||
|
||||
return (n == 0) ? 0 : errno;
|
||||
}
|
||||
|
||||
static int check_lock(int fd, char *fname)
|
||||
{
|
||||
struct stat fs = {0}, ds = {0};
|
||||
|
||||
/* You might grab a lock on a file, but the file
|
||||
* might be changed just before you grabbed the lock. Detect that and fail..
|
||||
*/
|
||||
if (fstat(fd, &ds) < 0 ||
|
||||
stat(fname, &fs) < 0 ||
|
||||
|
||||
ds.st_nlink != fs.st_nlink ||
|
||||
memcmp(&ds.st_dev,&fs.st_dev, sizeof ds.st_dev) != 0 ||
|
||||
memcmp(&ds.st_ino,&fs.st_ino, sizeof ds.st_ino) != 0 ||
|
||||
ds.st_uid != fs.st_uid ||
|
||||
ds.st_gid != fs.st_gid ||
|
||||
ds.st_size != fs.st_size)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mm_lockfile(int fd, char *fname, int shouldblock)
|
||||
{
|
||||
int ret = lockfile(fd,shouldblock);
|
||||
|
||||
if (ret != 0 ||
|
||||
(ret = check_lock(fd,fname)) != 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __MMS_GLOBAL__INCLUDED__
|
||||
#define __MMS_GLOBAL__INCLUDED__
|
||||
#ifndef __MMS_UTIL__INCLUDED__
|
||||
#define __MMS_UTIL__INCLUDED__
|
||||
|
||||
#include "gwlib/gwlib.h"
|
||||
#include "gwlib/mime.h"
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include "mms_billing.h"
|
||||
#include "mms_resolve.h"
|
||||
#include "mms_detokenize.h"
|
||||
#include "mms_mmbox.h"
|
||||
|
||||
/* Send errors */
|
||||
#define MMS_SEND_OK 0
|
||||
|
@ -36,6 +37,7 @@ typedef struct MmsBoxSettings {
|
|||
Octstr *unified_prefix, *local_prefix;
|
||||
Octstr *sendmail;
|
||||
Octstr *global_queuedir, *mm1_queuedir, *mm4_queuedir;
|
||||
Octstr *mmbox_rootdir;
|
||||
|
||||
Octstr *ua_profile_cache_dir;
|
||||
|
||||
|
@ -79,7 +81,7 @@ typedef struct MmsBoxSettings {
|
|||
Octstr *mms_notify_txt;
|
||||
Octstr *mms_notify_unprov_txt;
|
||||
Octstr *mms_toolarge;
|
||||
Octstr *mmbox_host;
|
||||
Octstr *mmbox_host; /* XXX need to remove this. */
|
||||
|
||||
Octstr *mms_email_txt;
|
||||
Octstr *mms_email_html;
|
||||
|
@ -160,11 +162,20 @@ void mms_log(char *logmsg, Octstr *from, List *to,
|
|||
int msize, Octstr *msgid,
|
||||
Octstr *acct,
|
||||
Octstr *viaproxy,
|
||||
char *interface, Octstr *ua);
|
||||
char *interface,
|
||||
Octstr *ua);
|
||||
|
||||
void mms_log2(char *logmsg, Octstr *from, Octstr *to,
|
||||
int msize, Octstr *msgid,
|
||||
Octstr *acct,
|
||||
Octstr *viaproxy,
|
||||
char *interface, Octstr *ua);
|
||||
char *interface,
|
||||
Octstr *ua);
|
||||
|
||||
/*
|
||||
* lockfile: tries to lock a file, returns 0 if success, errno (which could be +ve) otherwise.
|
||||
* we use flock()
|
||||
*/
|
||||
int mm_lockfile(int fd, char *fname, int shouldblock);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
#include "mms_queue.h"
|
||||
#include "mms_uaprof.h"
|
||||
#include "mms_util.h"
|
||||
#include "mms_mmbox.h"
|
||||
|
||||
static Octstr *data;
|
||||
static Octstr *from;
|
||||
static List *to;
|
||||
static MmsMsg *m;
|
||||
static int savetommbox;
|
||||
Octstr *mmbox;
|
||||
|
||||
static MmsBoxSettings *settings;
|
||||
|
||||
|
@ -20,7 +23,10 @@ static int find_own(int i, int argc, char *argv[])
|
|||
return 1;
|
||||
} else
|
||||
return -1;
|
||||
else if (argv[i][1] == 't')
|
||||
else if (argv[i][1] == 'b') {
|
||||
savetommbox = 1;
|
||||
return 0;
|
||||
} else if (argv[i][1] == 't')
|
||||
if (i + 1 < argc) {
|
||||
int j, m;
|
||||
List *l = octstr_split(octstr_create(argv[i+1]),
|
||||
|
@ -143,10 +149,51 @@ int main(int argc, char *argv[])
|
|||
s = mms_queue_add(from, to, NULL, NULL, NULL, NULL, time(NULL),
|
||||
time(NULL) + settings->default_msgexpiry, m,
|
||||
NULL, 0, octstr_get_cstr(settings->global_queuedir));
|
||||
|
||||
if (savetommbox)
|
||||
mmbox = mms_mmbox_addmsg(octstr_get_cstr(settings->mmbox_rootdir),
|
||||
octstr_get_cstr(from), m, octstr_imm("Sent"));
|
||||
|
||||
mms_log("Received", from, to, msize, s, NULL, NULL, "mmssend",NULL);
|
||||
|
||||
printf("Queued: %s\n", octstr_get_cstr(s));
|
||||
printf("Queued: %s, mmbox=%s\n",
|
||||
octstr_get_cstr(s), mmbox ? octstr_get_cstr(mmbox) : "");
|
||||
octstr_destroy(s);
|
||||
|
||||
#if 0
|
||||
List *l = list_create();
|
||||
|
||||
list_append(l, octstr_imm("+testing"));
|
||||
list_append(l, octstr_imm("-naughty"));
|
||||
list_append(l, octstr_imm("+adult"));
|
||||
list_append(l, octstr_imm("+adult"));
|
||||
list_append(l, octstr_imm("+adult-2"));
|
||||
int ret = mms_mmbox_modmsg(octstr_get_cstr(settings->mmbox_rootdir),
|
||||
octstr_get_cstr(from),
|
||||
octstr_imm("h-cs-df1111155064.1.x898915"),
|
||||
octstr_imm("Draft"), l);
|
||||
|
||||
#else
|
||||
|
||||
List *l = list_create();
|
||||
List *sl = list_create();
|
||||
|
||||
|
||||
// list_append(l, octstr_imm("/naughty"));
|
||||
|
||||
list_append(sl, octstr_imm("Draft"));
|
||||
l = mms_mmbox_search(octstr_get_cstr(settings->mmbox_rootdir),
|
||||
octstr_get_cstr(from), sl, l, -1, 2000);
|
||||
|
||||
int ii;
|
||||
|
||||
for (ii = 0; ii<list_len(l); ii++)
|
||||
printf("%s\n", octstr_get_cstr(list_get(l,ii)));
|
||||
|
||||
MmsMsg *mm = mms_mmbox_get(octstr_get_cstr(settings->mmbox_rootdir),
|
||||
octstr_get_cstr(from), octstr_imm("h-cs-df1111155064.1.x898915"));
|
||||
if (mm)
|
||||
mms_msgdump(mm,1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue