<commit_before>/*
 *
 *  OBEX Server
 *
 *  Copyright (C) 2007-2010  Nokia Corporation
 *  Copyright (C) 2007-2010  <NAME> <<EMAIL>>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>

#include <openobex/obex.h>
#include <openobex/obex_const.h>

#include <glib.h>

#include "plugin.h"
#include "service.h"
#include "logging.h"
#include "obex.h"
#include "dbus.h"

#define VCARD_TYPE "text/x-vcard"
#define VCARD_FILE CONFIGDIR "/vcard.vcf"

#define OPP_CHANNEL	9
#define OPP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>	\
<record>									\
  <attribute id=\"0x0001\">							\
    <sequence>									\
      <uuid value=\"0x1105\"/>							\
    </sequence>									\
  </attribute>									\
										\
  <attribute id=\"0x0004\">							\
    <sequence>									\
      <sequence>								\
        <uuid value=\"0x0100\"/>						\
      </sequence>								\
      <sequence>								\
        <uuid value=\"0x0003\"/>						\
        <uint8 value=\"%u\" name=\"channel\"/>					\
      </sequence>								\
      <sequence>								\
        <uuid value=\"0x0008\"/>						\
      </sequence>								\
    </sequence>									\
  </attribute>									\
										\
  <attribute id=\"0x0009\">							\
    <sequence>									\
      <sequence>								\
        <uuid value=\"0x1105\"/>						\
        <uint16 value=\"0x0100\" name=\"version\"/>				\
      </sequence>								\
    </sequence>									\
  </attribute>									\
										\
  <attribute id=\"0x0100\">							\
    <text value=\"%s\" name=\"name\"/>						\
  </attribute>									\
										\
  <attribute id=\"0x0303\">							\
    <sequence>									\
      <uint8 value=\"0x01\"/>							\
      <uint8 value=\"0x01\"/>							\
      <uint8 value=\"0x02\"/>							\
      <uint8 value=\"0x03\"/>							\
      <uint8 value=\"0x04\"/>							\
      <uint8 value=\"0x05\"/>							\
      <uint8 value=\"0x06\"/>							\
      <uint8 value=\"0xff\"/>							\
    </sequence>									\
  </attribute>									\
</record>"

static void opp_connect(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os = OBEX_GetUserData(obex);

	register_transfer(os->cid, os);
	/* OPP doesn't contains target or connection id. */
	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
}

static void opp_progress(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os = OBEX_GetUserData(obex);

	emit_transfer_progress(os->cid, os->size, os->offset);
}

static gint opp_chkput(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;
	gchar *new_folder, *new_name;
	gint32 time;
	gint ret;

	os = OBEX_GetUserData(obex);
	if (os == NULL)
		return -EINVAL;

	if (!os->name)
		return -EINVAL;

	if (os->size == OBJECT_SIZE_DELETE)
		return -EINVAL;

	if (os->server->auto_accept)
		goto skip_auth;

	time = 0;
	ret = request_authorization(os->cid, OBEX_GetFD(obex),
					os->name ? os->name : "",
					os->type ? os->type : "",
					os->size, time, &new_folder,
					&new_name);

	if (ret < 0)
		return -EPERM;

	if (new_folder) {
		g_free(os->current_folder);
		os->current_folder = new_folder;
	}

	if (new_name) {
		g_free(os->name);
		os->name = new_name;
	}

skip_auth:
	emit_transfer_started(os->cid);
	return os_prepare_put(os);
}

static void opp_put(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;

	os = OBEX_GetUserData(obex);
	if (os == NULL)
		return;

	if (os->current_folder == NULL) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		return;
	}

	if (os->name == NULL) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_BAD_REQUEST, OBEX_RSP_BAD_REQUEST);
		return;
	}

	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
}

static void opp_get(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;
	obex_headerdata_t hv;
	size_t size;

	os = OBEX_GetUserData(obex);
	if (os == NULL)
		return;

	if (os->name)
		goto fail;

	if (os->type == NULL)
		goto fail;

	if (g_str_equal(os->type, VCARD_TYPE)) {
		if (os_prepare_get(os, VCARD_FILE, &size) < 0)
			goto fail;
	} else
		goto fail;


	hv.bq4 = size;
	OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_LENGTH, hv, 4, 0);

	/* Add body header */<commit_msg>obexd: Fix error code response when there's no default vCard<commit_after>/*
 *
 *  OBEX Server
 *
 *  Copyright (C) 2007-2010  Nokia Corporation
 *  Copyright (C) 2007-2010  <NAME> <<EMAIL>>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>

#include <openobex/obex.h>
#include <openobex/obex_const.h>

#include <glib.h>

#include "plugin.h"
#include "service.h"
#include "logging.h"
#include "obex.h"
#include "dbus.h"

#define VCARD_TYPE "text/x-vcard"
#define VCARD_FILE CONFIGDIR "/vcard.vcf"

#define OPP_CHANNEL	9
#define OPP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>	\
<record>									\
  <attribute id=\"0x0001\">							\
    <sequence>									\
      <uuid value=\"0x1105\"/>							\
    </sequence>									\
  </attribute>									\
										\
  <attribute id=\"0x0004\">							\
    <sequence>									\
      <sequence>								\
        <uuid value=\"0x0100\"/>						\
      </sequence>								\
      <sequence>								\
        <uuid value=\"0x0003\"/>						\
        <uint8 value=\"%u\" name=\"channel\"/>					\
      </sequence>								\
      <sequence>								\
        <uuid value=\"0x0008\"/>						\
      </sequence>								\
    </sequence>									\
  </attribute>									\
										\
  <attribute id=\"0x0009\">							\
    <sequence>									\
      <sequence>								\
        <uuid value=\"0x1105\"/>						\
        <uint16 value=\"0x0100\" name=\"version\"/>				\
      </sequence>								\
    </sequence>									\
  </attribute>									\
										\
  <attribute id=\"0x0100\">							\
    <text value=\"%s\" name=\"name\"/>						\
  </attribute>									\
										\
  <attribute id=\"0x0303\">							\
    <sequence>									\
      <uint8 value=\"0x01\"/>							\
      <uint8 value=\"0x01\"/>							\
      <uint8 value=\"0x02\"/>							\
      <uint8 value=\"0x03\"/>							\
      <uint8 value=\"0x04\"/>							\
      <uint8 value=\"0x05\"/>							\
      <uint8 value=\"0x06\"/>							\
      <uint8 value=\"0xff\"/>							\
    </sequence>									\
  </attribute>									\
</record>"

static void opp_connect(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os = OBEX_GetUserData(obex);

	register_transfer(os->cid, os);
	/* OPP doesn't contains target or connection id. */
	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
}

static void opp_progress(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os = OBEX_GetUserData(obex);

	emit_transfer_progress(os->cid, os->size, os->offset);
}

static gint opp_chkput(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;
	gchar *new_folder, *new_name;
	gint32 time;
	gint ret;

	os = OBEX_GetUserData(obex);
	if (os == NULL)
		return -EINVAL;

	if (!os->name)
		return -EINVAL;

	if (os->size == OBJECT_SIZE_DELETE)
		return -EINVAL;

	if (os->server->auto_accept)
		goto skip_auth;

	time = 0;
	ret = request_authorization(os->cid, OBEX_GetFD(obex),
					os->name ? os->name : "",
					os->type ? os->type : "",
					os->size, time, &new_folder,
					&new_name);

	if (ret < 0)
		return -EPERM;

	if (new_folder) {
		g_free(os->current_folder);
		os->current_folder = new_folder;
	}

	if (new_name) {
		g_free(os->name);
		os->name = new_name;
	}

skip_auth:
	emit_transfer_started(os->cid);
	return os_prepare_put(os);
}

static void opp_put(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;

	os = OBEX_GetUserData(obex);
	if (os == NULL)
		return;

	if (os->current_folder == NULL) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		return;
	}

	if (os->name == NULL) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_BAD_REQUEST, OBEX_RSP_BAD_REQUEST);
		return;
	}

	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
}

static void opp_get(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;
	obex_headerdata_t hv;
	size_t size;

	os = OBEX_GetUserData(obex);
	if (os == NULL)
		return;

	if (os->name)
		goto fail;

	if (os->type == NULL)
		goto fail;

	if (g_str_equal(os->type, VCARD_TYPE)) {
		if (os_prepare_get(os, VCARD_FILE, &size) < 0) {
			OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_FOUND,
					OBEX_RSP_NOT_FOUND);
			return;
		}
	} else
		goto fail;


	hv.bq4 = size;
	OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_LENGTH, hv, 4, 0);

	/* Add body header */
{'fraction_non_alphanumeric': 0.14538648320518008, 'fraction_numerical': 0.025900445163901255, 'mean_word_length': 2.4062715368711234, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 2, '>': 157, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1635623', 'n_tokens_mistral': 4554, 'n_tokens_neox': 3739, 'n_words': 849}