Commit 62fde257 authored by Slava Monich's avatar Slava Monich

Merge branch 'fd' into 'master'

Add sendMessageFd D-Bus API

See merge request !27
parents 3a0b9d01 558a25ac
......@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
......@@ -51,6 +51,7 @@ typedef struct mms_app_dbus_policy {
#define MMS_ENGINE_DBUS_METHOD_RECEIVE_MESSAGE "receiveMessage"
#define MMS_ENGINE_DBUS_METHOD_SEND_READ_REPORT "sendReadReport"
#define MMS_ENGINE_DBUS_METHOD_SEND_MESSAGE "sendMessage"
#define MMS_ENGINE_DBUS_METHOD_SEND_MESSAGE_FD "sendMessageFd"
#define MMS_ENGINE_DBUS_METHOD_PUSH "push"
#define MMS_ENGINE_DBUS_METHOD_PUSH_NOTIFY "pushNotify"
#define MMS_ENGINE_DBUS_METHOD_SET_LOG_LEVEL "setLogLevel"
......@@ -60,8 +61,8 @@ typedef struct mms_app_dbus_policy {
#define MMS_ENGINE_DBUS_METHOD_EXIT "exit"
static const DA_ACTION mms_engine_dbus_actions[] = {
#define INIT_DA_ACTION(id) \
{MMS_ENGINE_DBUS_METHOD_##id, MMS_ENGINE_ACTION_##id, 0},
#define INIT_DA_ACTION(ID,id,name) \
{MMS_ENGINE_DBUS_METHOD_##ID, MMS_ENGINE_ACTION_##ID, 0},
MMS_ENGINE_DBUS_METHODS(INIT_DA_ACTION)
#undef INIT_DA_ACTION
{ NULL }
......@@ -73,6 +74,7 @@ static const MMSAppDBusPolicy mms_engine_default_dbus_policy = {
MMS_ENGINE_DBUS_METHOD_RECEIVE_MESSAGE "()|"
MMS_ENGINE_DBUS_METHOD_SEND_READ_REPORT"()|"
MMS_ENGINE_DBUS_METHOD_SEND_MESSAGE"()|"
MMS_ENGINE_DBUS_METHOD_SEND_MESSAGE_FD"()|"
MMS_ENGINE_DBUS_METHOD_SET_LOG_LEVEL"()|"
MMS_ENGINE_DBUS_METHOD_SET_LOG_TYPE"()|"
MMS_ENGINE_DBUS_METHOD_MIGRATE_SETTINGS"()|"
......
This diff is collapsed.
/*
* Copyright (C) 2013-2020 Jolla Ltd.
* Copyright (C) 2013-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019 Open Mobile Platform LLC.
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
......@@ -40,22 +40,23 @@
#endif /* MMS_ENGINE_CONFIG_FILE */
#define MMS_ENGINE_DBUS_METHODS(m) \
m(CANCEL) \
m(RECEIVE_MESSAGE) \
m(SEND_READ_REPORT) \
m(SEND_MESSAGE) \
m(PUSH) \
m(PUSH_NOTIFY) \
m(SET_LOG_LEVEL) \
m(SET_LOG_TYPE) \
m(GET_VERSION) \
m(MIGRATE_SETTINGS) \
m(EXIT)
m(CANCEL,cancel,"cancel") \
m(RECEIVE_MESSAGE,receive_message,"receive-message") \
m(SEND_READ_REPORT,send_read_report,"send-read-report") \
m(SEND_MESSAGE,send_message,"send-message") \
m(SEND_MESSAGE_FD,send_message_fd,"send-message-fd") \
m(PUSH,push,"push") \
m(PUSH_NOTIFY,push_notify,"push-notify") \
m(SET_LOG_LEVEL,set_log_level,"set-log-level") \
m(SET_LOG_TYPE,set_log_type,"set-log-type") \
m(GET_VERSION,get_version,"get-version") \
m(MIGRATE_SETTINGS,migrate_settings,"migrate-settings") \
m(EXIT,exit,"exit")
typedef enum mms_engine_action {
/* Action ids must be non-zero, shift those by one */
MMS_ENGINE_ACTION_NONE = 0,
#define MMS_ENGINE_ACTION_(id) MMS_ENGINE_ACTION_##id,
#define MMS_ENGINE_ACTION_(ID,id,name) MMS_ENGINE_ACTION_##ID,
MMS_ENGINE_DBUS_METHODS(MMS_ENGINE_ACTION_)
#undef MMS_ENGINE_ACTION_
} MMS_ENGINE_ACTION;
......
......@@ -160,6 +160,32 @@
<arg direction="out" type="s" name="imsiActual"/>
</method>
<!--
Does the same thing as sendMessage, all parameters have the
same meaning, the only difference is that parts contain file
descriptors rather than file names.
-->
<method name="sendMessageFd">
<arg direction="in" type="i" name="recId"/>
<arg direction="in" type="s" name="imsi"/>
<arg direction="in" type="as" name="to"/>
<arg direction="in" type="as" name="cc"/>
<arg direction="in" type="as" name="bcc"/>
<arg direction="in" type="s" name="subject"/>
<arg direction="in" type="u" name="flags"/>
<!--
Each variant in the parts array is (hsss):
h - file descriptor open for reading
s - file name, without directory
s - content type (including charset)
s - content id (optional)
-->
<arg direction="in" type="a(hsss)" name="parts"/>
<arg direction="out" type="s" name="imsiActual"/>
<annotation name="org.gtk.GDBus.C.UnixFD" value="1"/>
</method>
<!--
===============================================================
================== M I S C E L L A N E O U S ==================
......
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef SAILFISH_MMS_ATTACHMENT_INFO_H
#define SAILFISH_MMS_ATTACHMENT_INFO_H
#include "mms_lib_types.h"
/* Attachment information */
struct mms_attachment_info {
GMappedFile* map;
gsize size;
const void* data;
const char* file_name;
const char* content_type;
const char* content_id;
};
gboolean
mms_attachment_info_path(
MMSAttachmentInfo* ai,
const char* path,
const char* content_type,
const char* content_id,
GError** error);
gboolean
mms_attachment_info_fd(
MMSAttachmentInfo* ai,
int fd,
const char* name,
const char* content_type,
const char* content_id,
GError** error);
void
mms_attachment_info_cleanup(
MMSAttachmentInfo* ai);
#endif /* SAILFISH_MMS_ATTACHMENT_INFO_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
/*
* Copyright (C) 2013-2018 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2013-2020 Jolla Ltd.
* Copyright (C) 2013-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -8,12 +9,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef JOLLA_MMS_LIB_TYPES_H
#define JOLLA_MMS_LIB_TYPES_H
#ifndef SAILFISH_MMS_LIB_TYPES_H
#define SAILFISH_MMS_LIB_TYPES_H
#include <stdio.h>
#include <stdlib.h>
......@@ -43,17 +44,10 @@ typedef GLogModule MMSLogModule;
#ifdef __linux__
# define HAVE_MAGIC
# define HAVE_REALPATH
#endif
/* Attachment information */
typedef struct mms_attachment_info {
const char* file_name; /* Full path name */
const char* content_type; /* Content type */
const char* content_id; /* Content id */
} MMSAttachmentInfo;
/* Types */
typedef struct mms_attachment_info MMSAttachmentInfo;
typedef struct mms_config MMSConfig;
typedef struct mms_settings MMSSettings;
typedef struct mms_settings_sim_data MMSSettingsSimData;
......@@ -83,7 +77,7 @@ typedef enum _MMS_CONNECTION_TYPE {
MMS_CONNECTION_TYPE_USER /* Connection requested by user */
} MMS_CONNECTION_TYPE;
#endif /* JOLLA_MMS_LIB_TYPES_H */
#endif /* SAILFISH_MMS_LIB_TYPES_H */
/*
* Local Variables:
......
......@@ -65,6 +65,7 @@ HEADERS += \
src/mms_util.h \
HEADERS += \
include/mms_attachment_info.h \
include/mms_connection.h \
include/mms_connman.h \
include/mms_dispatcher.h \
......
This diff is collapsed.
......@@ -9,10 +9,11 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "mms_attachment_info.h"
#include "mms_file_util.h"
#include "mms_error.h"
......@@ -54,25 +55,18 @@ mms_smil_parse_end(
*/
gboolean
mms_file_is_smil(
const char* file)
const MMSAttachmentInfo* ai)
{
static const GMarkupParser toplevel = { mms_smil_parse_start,
mms_smil_parse_end, NULL, NULL, NULL };
gboolean smil = FALSE;
GMappedFile* map = g_mapped_file_new(file, FALSE, NULL);
if (map) {
gboolean smil_found = FALSE;
GMarkupParseContext* parser = g_markup_parse_context_new(&toplevel,
G_MARKUP_TREAT_CDATA_AS_TEXT, &smil_found, NULL);
if (g_markup_parse_context_parse(parser,
g_mapped_file_get_contents(map),
g_mapped_file_get_length(map), NULL)) {
g_markup_parse_context_end_parse(parser, NULL);
smil = smil_found;
}
g_mapped_file_unref(map);
g_markup_parse_context_free(parser);
gboolean smil = FALSE, smil_found = FALSE;
GMarkupParseContext* parser = g_markup_parse_context_new(&toplevel,
G_MARKUP_TREAT_CDATA_AS_TEXT, &smil_found, NULL);
if (g_markup_parse_context_parse(parser, ai->data, ai->size, NULL)) {
g_markup_parse_context_end_parse(parser, NULL);
smil = smil_found;
}
g_markup_parse_context_free(parser);
return smil;
}
......@@ -200,46 +194,29 @@ mms_write_bytes(
}
/**
* Copies the file. Assumes that the destination directory exists.
* Copies attachment to a file. Assumes that the destination directory
* already exists.
*/
gboolean
mms_file_copy(
const char* src,
mms_copy_attachment(
const MMSAttachmentInfo* ai,
const char* dest,
GError** error)
{
gboolean ok = FALSE;
int out = open(dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, MMS_FILE_PERM);
if (out >= 0) {
int in = open(src, O_RDONLY | O_BINARY);
if (in >= 0) {
int nbytes;
const size_t buflen = 4096;
void* buf = g_malloc(buflen);
if (write(out, ai->data, ai->size) == (gssize)ai->size) {
ok = TRUE;
while ((nbytes = read(in, buf, buflen)) > 0) {
if (write(out, buf, nbytes) < nbytes) {
ok = FALSE;
MMS_ERROR(error, MMS_LIB_ERROR_IO,
"Failed to write %s: %s", dest, strerror(errno));
break;
}
}
if (nbytes < 0) {
ok = FALSE;
MMS_ERROR(error, MMS_LIB_ERROR_IO,
"Failed to read %s: %s", src, strerror(errno));
}
g_free(buf);
close(in);
} else {
MMS_ERROR(error, MMS_LIB_ERROR_IO,
"Failed to open file %s: %s", src, strerror(errno));
MMS_ERROR(error, MMS_LIB_ERROR_IO, "Failed to write %s: %s",
dest, strerror(errno));
}
close(out);
} else {
MMS_ERROR(error, MMS_LIB_ERROR_IO,
"Failed to create file %s: %s", dest, strerror(errno));
MMS_ERROR(error, MMS_LIB_ERROR_IO, "Failed to create file %s: %s",
dest, strerror(errno));
}
return ok;
}
......
......@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
......@@ -45,7 +45,7 @@
gboolean
mms_file_is_smil(
const char* file);
const MMSAttachmentInfo* ai);
void
mms_remove_file_and_dir(
......@@ -81,8 +81,8 @@ mms_write_bytes(
char** path);
gboolean
mms_file_copy(
const char* src,
mms_copy_attachment(
const MMSAttachmentInfo* parts,
const char* dest,
GError** error);
......
......@@ -9,12 +9,13 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "mms_task.h"
#include "mms_attachment.h"
#include "mms_attachment_info.h"
#include "mms_dispatcher.h"
#include "mms_settings.h"
#include "mms_handler.h"
......@@ -457,24 +458,29 @@ mms_task_encode_prepare_attachments(
int smil_index = -1;
GPtrArray* array = g_ptr_array_sized_new(nparts);
for (i=0; i<nparts; i++) {
const MMSAttachmentInfo* part = parts + i;
MMSAttachment* attachment = NULL;
MMSAttachmentInfo info = parts[i];
char* path;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
path = mms_task_encode_generate_path(dir,
g_basename(info.file_name), info.content_type);
g_basename(part->file_name), part->content_type);
G_GNUC_END_IGNORE_DEPRECATIONS;
if (mms_file_copy(info.file_name, path, error)) {
info.file_name = path;
attachment = mms_attachment_new(config, &info, error);
if (attachment) {
if (smil_index < 0 &&
(attachment->flags & MMS_ATTACHMENT_SMIL)) {
smil_index = i;
if (mms_copy_attachment(part, path, error)) {
MMSAttachmentInfo ai;
if (mms_attachment_info_path(&ai, path, part->content_type,
part->content_id, error)) {
attachment = mms_attachment_new(config, &ai, error);
if (attachment) {
if (smil_index < 0 && (attachment->flags &
MMS_ATTACHMENT_SMIL)) {
smil_index = i;
}
g_ptr_array_add(array, attachment);
}
g_ptr_array_add(array, attachment);
mms_attachment_info_cleanup(&ai);
}
} else if (error && *error) {
GERR("%s", GERRMSG(*error));
......
/*
* Copyright (C) 2013-2020 Jolla Ltd.
* Copyright (C) 2013-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -15,6 +16,7 @@
#include "test_util.h"
#include "mms_attachment.h"
#include "mms_attachment_info.h"
#include "mms_settings.h"
#include "mms_lib_util.h"
#include "mms_lib_log.h"
......@@ -381,13 +383,19 @@ run_test(
g_assert(dir);
testfile = g_build_filename(dir, name, NULL);
g_assert(mms_file_copy(test->file, testfile, NULL));
/* Copy the file */
g_assert(mms_attachment_info_path(&info, test->file, NULL, NULL, &error));
g_assert(mms_copy_attachment(&info, testfile, &error));
mms_attachment_info_cleanup(&info);
mms_settings_sim_data_default(&sim_settings);
sim_settings.max_pixels = test->max_pixels;
info.file_name = testfile;
info.content_type = test->type->content_type;
info.content_id = name;
/* Create the attachment */
g_assert(mms_attachment_info_path(&info, testfile,test->type->content_type,
name, &error));
at = mms_attachment_new(&config, &info, &error);
mms_attachment_info_cleanup(&info);
g_assert(at);
for (i = 0; i < test->steps && ok; i++) {
......
......@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
......@@ -24,6 +24,7 @@
#include "mms_lib_util.h"
#include "mms_settings.h"
#include "mms_dispatcher.h"
#include "mms_attachment_info.h"
#include <gutil_macros.h>
#include <gutil_log.h>
......@@ -34,9 +35,15 @@
static TestOpt test_opt;
typedef struct test_attachment {
const char* file_name;
const char* content_type;
const char* content_id;
} TestAttachment;
typedef struct test_desc {
const char* name;
const MMSAttachmentInfo* parts;
const TestAttachment* parts;
int nparts;
gsize size_limit;
const char* subject;
......@@ -84,25 +91,27 @@ typedef struct test {
GMappedFile* resp_file;
} Test;
static const MMSAttachmentInfo test_files_accept [] = {
static const TestAttachment test_files_accept [] = {
{ "smil", "application/smil;charset=us-ascii", NULL },
{ "0001.jpg", "image/jpeg;name=0001.jpg", "image" },
{ "test.txt", "text/plain;charset=utf-8;name=wrong.name", "text" }
};
static const MMSAttachmentInfo test_files_accept_no_ext [] = {
#ifdef HAVE_MAGIC
static const TestAttachment test_files_accept_no_ext [] = {
{ "smil", NULL, NULL },
{ "0001", NULL, "image1" },
{ "0001", "", "image2" },
{ "test.text", "text/plain;charset=utf-8", "text" }
};
#endif /* HAVE_MAGIC */
static const MMSAttachmentInfo test_files_reject [] = {
static const TestAttachment test_files_reject [] = {
{ "0001.png", "image/png", "image" },
{ "test.txt", "text/plain", "text" }
};
static const MMSAttachmentInfo test_txt [] = {
static const TestAttachment test_txt [] = {
{ "test.txt", NULL, "text" }
};
......@@ -126,6 +135,7 @@ static const TestDesc send_tests[] = {
NULL,
"TestMessageId"
},{
#ifdef HAVE_MAGIC
"AcceptNoExt",
ATTACHMENTS(test_files_accept_no_ext),
0,
......@@ -142,6 +152,7 @@ static const TestDesc send_tests[] = {
NULL,
"TestMessageId"
},{
#endif /* HAVE_MAGIC */
"ServiceDenied",
ATTACHMENTS(test_files_reject),
0,
......@@ -348,7 +359,8 @@ run_test(
GError* error = NULL;
TestDirs dirs;
Test test;
guint port, i;
guint port;
int i;
const char* id;
char* imsi;
char* imsi2;
......@@ -383,8 +395,9 @@ run_test(
for (i = 0; i < desc->nparts; i++) {
test.files[i] = g_build_filename(DATA_DIR, desc->name,
desc->parts[i].file_name, NULL);
test.parts[i] = desc->parts[i];
test.parts[i].file_name = test.files[i];
g_assert(mms_attachment_info_path(test.parts + i, test.files[i],
desc->parts[i].content_type, desc->parts[i].content_id, &error));
}
test.config = &config;
test.desc = desc;
......@@ -434,9 +447,6 @@ run_test(
}
/* Done */
g_free(imsi);
g_free(imsi2);
test_http_close(test.http);
test_http_unref(test.http);
mms_connman_test_close_connection(test.cm);
......@@ -445,11 +455,16 @@ run_test(
mms_dispatcher_unref(test.disp);
g_main_loop_unref(test.loop);
if (test.resp_file) g_mapped_file_unref(test.resp_file);
for (i = 0; i < test.desc->nparts; i++) g_free(test.files[i]);
for (i = 0; i < test.desc->nparts; i++) {
mms_attachment_info_cleanup(test.parts + i);
g_free(test.files[i]);
}
g_free(test.files);
g_free(test.parts);
g_free(test.id);
g_free(imsi);
g_free(imsi2);
test_dirs_cleanup(&dirs, TRUE);
}
......
/*
* Copyright (C) 2013-2019 Jolla Ltd.
* Copyright (C) 2013-2020 Jolla Ltd.
* Copyright (C) 2013-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -7,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
......@@ -18,13 +20,18 @@
#include <stdlib.h>
#include <string.h>
#include <gutil_log.h>
#include <gutil_strv.h>
#include <gio/gunixfdlist.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* Generated headers */
#include "org.nemomobile.MmsEngine.h"
static const char pname[] = "mms-send";
enum app_ret_value {
RET_OK,
RET_ERR_CMDLINE,
......@@ -41,73 +48,138 @@ typedef struct mms_send_opt {
#define MMS_SEND_REQUEST_DELIVERY_REPORT (0x01)
#define MMS_SEND_REQUEST_READ_REPORT (0x02)
#define MMS_SEND_REQUEST_LEGACY_API (0x04)
static
char*
mms_send(
mms_send_proxy(
OrgNemomobileMmsEngine* proxy,
char* files[],
int count,
const MmsSendOpt* opt)
{
char* imsi_out = NULL;
int i;
GError* error = NULL;
OrgNemomobileMmsEngine* proxy =
org_nemomobile_mms_engine_proxy_new_for_bus_sync(
G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
"org.nemomobile.MmsEngine", "/", NULL, &error);
GVariant* parts = NULL;
GVariantBuilder gb;
char* imsi_out = NULL;
char** to_list = g_strsplit(opt->to, ",", 0);
const char* imsi = opt->imsi ? opt->imsi : "";
const char* subject = opt->subject ? opt->subject : "";
const char* none = NULL;
gboolean ok = TRUE;
if (proxy) {
int i;
gboolean ok = TRUE;
if (opt->flags & MMS_SEND_REQUEST_LEGACY_API) {
char* fname = g_malloc(PATH_MAX);
GVariant* parts;
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("a(sss)"));
g_variant_builder_init(&gb, G_VARIANT_TYPE("a(sss)"));
for (i = 0; ok && i < count; i++) {
if (realpath(files[i], fname)) {
if (g_file_test(fname, G_FILE_TEST_IS_REGULAR)) {
const char* ctype = gutil_strv_at(opt->ctype, i);
g_variant_builder_add(&b, "(sss)", fname,
g_variant_builder_add(&gb, "(sss)", fname,
ctype ? ctype : "", "");
} else {
fprintf(stderr, "%s: no such file: %s\n", pname, fname);
ok = FALSE;
continue;
}
GERR("no such file: %s\n", fname);
} else {
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
ok = FALSE;
GERR("%s: %s\n", fname, strerror(errno));
}
ok = FALSE;
}
parts = g_variant_ref_sink(g_variant_builder_end(&b));
if (ok) {
char** to_list = g_strsplit(opt->to, ",", 0);
const char* imsi = opt->imsi ? opt->imsi : "";
const char* subject = opt->subject ? opt->subject : "";
const char* none = NULL;
if (!org_nemomobile_mms_engine_call_send_message_sync(proxy,
parts = g_variant_ref_sink(g_variant_builder_end(&gb));
org_nemomobile_mms_engine_call_send_message_sync(proxy,
0, imsi, (const gchar* const*)to_list, &none, &none,
subject, opt->flags, parts, &imsi_out, NULL, &error)) {
/* D-Bus error */
fprintf(stderr, "%s\n", error->message);
g_error_free(error);
subject, opt->flags, parts, &imsi_out, NULL, &error);
}
g_free(fname);
} else {
int* fds = g_new(int, count);
g_variant_builder_init(&gb, G_VARIANT_TYPE("a(hsss)"));
for (i = 0; i < count; i++) {
const char* fname = files[i];
fds[i] = open(fname, O_RDONLY, 0);
if (fds[i] >= 0) {
struct stat st;
if (!fstat(fds[i], &st)) {
if (S_ISREG(st.st_mode)) {
char* basename = g_path_get_basename(fname);
const char* ctype = gutil_strv_at(opt->ctype, i);
g_variant_builder_add(&gb, "(@hsss)",
g_variant_new_handle(i), basename,
ctype ? ctype : "", "");
g_free(basename);
continue;
} else {
GERR("not a regular file: %s", fname);
}