tizen 2.3 release
[framework/connectivity/bluez.git] / obexd / plugins / opp.c
1 /*
2  *
3  *  OBEX Server
4  *
5  *  Copyright (C) 2007-2010  Nokia Corporation
6  *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <errno.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <inttypes.h>
33
34 #include <glib.h>
35
36 #include "obexd.h"
37 #include "plugin.h"
38 #include "obex.h"
39 #include "service.h"
40 #include "log.h"
41 #include "manager.h"
42 #include "filesystem.h"
43
44 #define VCARD_TYPE "text/x-vcard"
45 #define VCARD_FILE CONFIGDIR "/vcard.vcf"
46
47 static void *opp_connect(struct obex_session *os, int *err)
48 {
49         manager_register_session(os);
50
51         if (err)
52                 *err = 0;
53
54         return manager_register_transfer(os);
55 }
56
57 static void opp_progress(struct obex_session *os, void *user_data)
58 {
59         manager_emit_transfer_progress(user_data);
60 }
61
62 static int opp_chkput(struct obex_session *os, void *user_data)
63 {
64         char *folder, *name, *path;
65         int32_t time;
66         const char *t;
67         int err;
68
69         if (obex_get_size(os) == OBJECT_SIZE_DELETE)
70                 return -ENOSYS;
71
72         t = obex_get_name(os);
73         if (t != NULL && !is_filename(t))
74                 return -EBADR;
75
76         if (obex_option_auto_accept()) {
77                 folder = g_strdup(obex_option_root_folder());
78                 name = g_strdup(obex_get_name(os));
79                 goto skip_auth;
80         }
81
82         time = 0;
83         err = manager_request_authorization(user_data, time, &folder, &name);
84         if (err < 0)
85                 return -EPERM;
86
87         if (folder == NULL)
88                 folder = g_strdup(obex_option_root_folder());
89
90         if (name == NULL)
91                 name = g_strdup(obex_get_name(os));
92
93 skip_auth:
94         if (name == NULL || strlen(name) == 0) {
95                 err = -EBADR;
96                 goto failed;
97         }
98
99         if (g_strcmp0(name, obex_get_name(os)) != 0)
100                 obex_set_name(os, name);
101
102         path = g_build_filename(folder, name, NULL);
103
104         err = obex_put_stream_start(os, path);
105
106         g_free(path);
107
108         if (err < 0)
109                 goto failed;
110
111         manager_emit_transfer_started(user_data);
112
113 failed:
114         g_free(folder);
115         g_free(name);
116
117         return err;
118 }
119
120 static int opp_put(struct obex_session *os, void *user_data)
121 {
122         const char *name = obex_get_name(os);
123         const char *folder = obex_option_root_folder();
124
125         if (folder == NULL)
126                 return -EPERM;
127
128         if (name == NULL)
129                 return -EBADR;
130
131         return 0;
132 }
133
134 static int opp_get(struct obex_session *os, void *user_data)
135 {
136         const char *type;
137
138         if (obex_get_name(os))
139                 return -EPERM;
140
141         type = obex_get_type(os);
142
143         if (type == NULL)
144                 return -EPERM;
145
146         if (g_ascii_strcasecmp(type, VCARD_TYPE) == 0) {
147                 if (obex_get_stream_start(os, VCARD_FILE) < 0)
148                         return -ENOENT;
149
150         } else
151                 return -EPERM;
152
153         return 0;
154 }
155
156 static void opp_disconnect(struct obex_session *os, void *user_data)
157 {
158         manager_unregister_transfer(user_data);
159         manager_unregister_session(os);
160 }
161
162 static void opp_reset(struct obex_session *os, void *user_data)
163 {
164         manager_emit_transfer_completed(user_data);
165 }
166
167 static struct obex_service_driver driver = {
168         .name = "Object Push server",
169         .service = OBEX_OPP,
170         .connect = opp_connect,
171         .progress = opp_progress,
172         .disconnect = opp_disconnect,
173         .get = opp_get,
174         .put = opp_put,
175         .chkput = opp_chkput,
176         .reset = opp_reset
177 };
178
179 static int opp_init(void)
180 {
181         return obex_service_driver_register(&driver);
182 }
183
184 static void opp_exit(void)
185 {
186         obex_service_driver_unregister(&driver);
187 }
188
189 OBEX_PLUGIN_DEFINE(opp, opp_init, opp_exit)