opp.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * OBEX Server
  5. *
  6. * Copyright (C) 2007-2010 Nokia Corporation
  7. * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #include <errno.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <inttypes.h>
  18. #include <glib.h>
  19. #include "obexd/src/obexd.h"
  20. #include "obexd/src/plugin.h"
  21. #include "obexd/src/obex.h"
  22. #include "obexd/src/service.h"
  23. #include "obexd/src/log.h"
  24. #include "obexd/src/manager.h"
  25. #include "filesystem.h"
  26. #define VCARD_TYPE "text/x-vcard"
  27. static void *opp_connect(struct obex_session *os, int *err)
  28. {
  29. manager_register_session(os);
  30. if (err)
  31. *err = 0;
  32. return manager_register_transfer(os);
  33. }
  34. static void opp_progress(struct obex_session *os, void *user_data)
  35. {
  36. manager_emit_transfer_progress(user_data);
  37. }
  38. static int opp_chkput(struct obex_session *os, void *user_data)
  39. {
  40. char *folder, *name, *path;
  41. const char *t;
  42. int err;
  43. if (obex_get_size(os) == OBJECT_SIZE_DELETE)
  44. return -ENOSYS;
  45. t = obex_get_name(os);
  46. if (t != NULL && !is_filename(t))
  47. return -EBADR;
  48. if (obex_option_auto_accept()) {
  49. folder = g_strdup(obex_option_root_folder());
  50. name = g_strdup(obex_get_name(os));
  51. goto skip_auth;
  52. }
  53. err = manager_request_authorization(user_data, &folder, &name);
  54. if (err < 0)
  55. return -EPERM;
  56. if (folder == NULL)
  57. folder = g_strdup(obex_option_root_folder());
  58. if (name == NULL)
  59. name = g_strdup(obex_get_name(os));
  60. skip_auth:
  61. if (name == NULL || strlen(name) == 0) {
  62. err = -EBADR;
  63. goto failed;
  64. }
  65. if (g_strcmp0(name, obex_get_name(os)) != 0)
  66. obex_set_name(os, name);
  67. path = g_build_filename(folder, name, NULL);
  68. err = obex_put_stream_start(os, path);
  69. g_free(path);
  70. if (err < 0)
  71. goto failed;
  72. manager_emit_transfer_started(user_data);
  73. failed:
  74. g_free(folder);
  75. g_free(name);
  76. return err;
  77. }
  78. static int opp_put(struct obex_session *os, void *user_data)
  79. {
  80. const char *name = obex_get_name(os);
  81. const char *folder = obex_option_root_folder();
  82. if (folder == NULL)
  83. return -EPERM;
  84. if (name == NULL)
  85. return -EBADR;
  86. return 0;
  87. }
  88. static int opp_get(struct obex_session *os, void *user_data)
  89. {
  90. const char *type;
  91. char *folder, *path;
  92. int err = 0;
  93. if (obex_get_name(os))
  94. return -EPERM;
  95. type = obex_get_type(os);
  96. if (type == NULL)
  97. return -EPERM;
  98. folder = g_strdup(obex_option_root_folder());
  99. path = g_build_filename(folder, "/vcard.vcf", NULL);
  100. if (g_ascii_strcasecmp(type, VCARD_TYPE) == 0) {
  101. if (obex_get_stream_start(os, path) < 0)
  102. err = -ENOENT;
  103. } else
  104. err = -EPERM;
  105. g_free(folder);
  106. g_free(path);
  107. return err;
  108. }
  109. static void opp_disconnect(struct obex_session *os, void *user_data)
  110. {
  111. manager_unregister_transfer(user_data);
  112. manager_unregister_session(os);
  113. }
  114. static void opp_reset(struct obex_session *os, void *user_data)
  115. {
  116. manager_emit_transfer_completed(user_data);
  117. }
  118. static struct obex_service_driver driver = {
  119. .name = "Object Push server",
  120. .service = OBEX_OPP,
  121. .connect = opp_connect,
  122. .progress = opp_progress,
  123. .disconnect = opp_disconnect,
  124. .get = opp_get,
  125. .put = opp_put,
  126. .chkput = opp_chkput,
  127. .reset = opp_reset
  128. };
  129. static int opp_init(void)
  130. {
  131. return obex_service_driver_register(&driver);
  132. }
  133. static void opp_exit(void)
  134. {
  135. obex_service_driver_unregister(&driver);
  136. }
  137. OBEX_PLUGIN_DEFINE(opp, opp_init, opp_exit)