Merge lp:~bluetooth/ubuntu/maverick/obexd/main into lp:ubuntu/maverick/obexd

Proposed by Baptiste Mille-Mathias
Status: Merged
Merge reported by: Daniel Holbach
Merged at revision: not available
Proposed branch: lp:~bluetooth/ubuntu/maverick/obexd/main
Merge into: lp:ubuntu/maverick/obexd
Diff against target: 10631 lines (+6085/-2141)
53 files modified
ChangeLog (+45/-0)
Makefile.am (+25/-7)
Makefile.in (+75/-35)
aclocal.m4 (+35/-0)
client/main.c (+28/-3)
client/session.c (+1/-1)
client/transfer.c (+6/-3)
compile (+143/-0)
config.h.in (+3/-0)
configure (+296/-24)
configure.ac (+23/-1)
debian/changelog (+40/-0)
debian/control (+2/-1)
debian/rules (+4/-0)
gdbus/object.c (+6/-2)
plugins/bluetooth.c (+609/-0)
plugins/filesystem.c (+126/-49)
plugins/filesystem.h (+2/-2)
plugins/ftp.c (+145/-169)
plugins/nokia-backup.c (+295/-0)
plugins/opp.c (+71/-61)
plugins/pbap.c (+633/-192)
plugins/phonebook-dummy.c (+491/-39)
plugins/phonebook-ebook.c (+332/-56)
plugins/phonebook-tracker.c (+825/-0)
plugins/phonebook.h (+74/-14)
plugins/syncevolution.c (+80/-72)
plugins/usb.c (+245/-0)
plugins/vcard.c (+327/-0)
plugins/vcard.h (+65/-0)
src/bluetooth.c (+0/-202)
src/bluetooth.h (+0/-34)
src/btio.c (+12/-12)
src/btio.h (+7/-7)
src/dbus.h (+2/-2)
src/logging.c (+32/-19)
src/main.c (+32/-186)
src/manager.c (+39/-412)
src/mimetype.c (+45/-12)
src/mimetype.h (+16/-14)
src/obex-priv.h (+23/-41)
src/obex.c (+422/-413)
src/obex.h (+16/-13)
src/plugin.c (+2/-2)
src/server.c (+146/-0)
src/server.h (+47/-0)
src/service.c (+8/-15)
src/service.h (+20/-18)
src/transport.c (+91/-0)
src/transport.h (+33/-0)
test/ftp-client (+9/-0)
test/pbap-client (+3/-0)
test/pull-business-card (+28/-8)
To merge this branch: bzr merge lp:~bluetooth/ubuntu/maverick/obexd/main
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+27440@code.launchpad.net
To post a comment you must log in.
8. By Baptiste Mille-Mathias

* New upstream release.
  - version 0.28:
    + Fix broken assumption about contacts.
    + Fix issue with exporting empty contacts.
    + Fix issue with not always including the TEL header.
    + Fix wrong response code for PBAP PUT operation.
    + Fix handling of Tracker optional parameters.
    + Fix queries for incoming and outgoing folders.
    + Fix ordering during folder listing.
    + Fix complex logic discovering the type of call.
    + Add support for the X-IRMC-CALL-DATETIME field.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2010-04-27 04:17:15 +0000
+++ ChangeLog 2010-06-15 19:18:33 +0000
@@ -1,3 +1,48 @@
1ver 0.28:
2 Fix broken assumption about contacts.
3 Fix issue with exporting empty contacts.
4 Fix issue with not always including the TEL header.
5 Fix wrong response code for PBAP PUT operation.
6 Fix handling of Tracker optional parameters.
7 Fix queries for incoming and outgoing folders.
8 Fix ordering during folder listing.
9 Fix complex logic discovering the type of call.
10 Add support for the X-IRMC-CALL-DATETIME field.
11
12ver 0.27:
13 Fix GET name handling with FTP service.
14 Fix service driver matching when who is not specified.
15 Fix object name not being updated when agent changes it.
16 Fix inconsistency when using vCard version 2.1.
17 Fix wrong response code to PUT requests for PBAP.
18 Fix crash on PBAP SetPhoneBook function.
19 Add support for transport drivers.
20 Add support for Nokia backup plugin.
21
22ver 0.26:
23 Fix the order of the calls handles.
24 Fix crash when receiving small objects.
25 Fix invalid memory access when removing a file.
26 Fix inverting the list with wrong search attribute.
27 Fix wrong response code for dummy PullvCardListing.
28 Fix sending the Not Found response asynchronously.
29 Fix not resetting buffered data count when resetting the session.
30 Add support for multiple telephone numbers.
31 Add support for the ADR filter.
32
33ver 0.25:
34 Fix issue with missing phonebook-tracker.c file.
35
36ver 0.24:
37 Fix bug when creating directories.
38 Fix error code when removing non-empty directory.
39 Fix PullBusinessCard not return transfer errors.
40 Fix MaxListCount handling for PBAP PullPhoneBook function.
41 Fix mimetype driver selection and default fallback.
42 Add support to the WHO header in mimetype drivers.
43 Add support for PBAP operations to the back-ends.
44 Add support for PBAP Tracker backend.
45
1ver 0.23:46ver 0.23:
2 Fix unneeded reset of session after a CONNECT.47 Fix unneeded reset of session after a CONNECT.
3 Fix folder and object names with enabled auto accept.48 Fix folder and object names with enabled auto accept.
449
=== modified file 'Makefile.am'
--- Makefile.am 2010-04-27 04:17:15 +0000
+++ Makefile.am 2010-06-15 19:18:33 +0000
@@ -29,9 +29,22 @@
29builtin_sources =29builtin_sources =
30builtin_nodist =30builtin_nodist =
3131
32builtin_modules += bluetooth
33builtin_sources += plugins/bluetooth.c
34
35if USB
36builtin_modules += usb
37builtin_sources += plugins/usb.c
38endif
39
32builtin_modules += filesystem40builtin_modules += filesystem
33builtin_sources += plugins/filesystem.c plugins/filesystem.h41builtin_sources += plugins/filesystem.c plugins/filesystem.h
3442
43if NOKIA_BACKUP
44builtin_modules += backup
45builtin_sources += plugins/nokia-backup.c
46endif
47
35builtin_modules += opp48builtin_modules += opp
36builtin_sources += plugins/opp.c49builtin_sources += plugins/opp.c
3750
@@ -39,7 +52,8 @@
39builtin_sources += plugins/ftp.c52builtin_sources += plugins/ftp.c
4053
41builtin_modules += pbap54builtin_modules += pbap
42builtin_sources += plugins/pbap.c plugins/phonebook.h55builtin_sources += plugins/pbap.c plugins/phonebook.h \
56 plugins/vcard.h plugins/vcard.c
4357
44builtin_modules += syncevolution58builtin_modules += syncevolution
45builtin_sources += plugins/syncevolution.c59builtin_sources += plugins/syncevolution.c
@@ -52,13 +66,15 @@
52 src/main.c src/obexd.h src/plugin.h src/plugin.c \66 src/main.c src/obexd.h src/plugin.h src/plugin.c \
53 src/logging.h src/logging.c src/btio.h src/btio.c \67 src/logging.h src/logging.c src/btio.h src/btio.c \
54 src/dbus.h src/manager.c src/obex.h src/obex.c \68 src/dbus.h src/manager.c src/obex.h src/obex.c \
55 src/obex-priv.h src/bluetooth.h src/bluetooth.c \69 src/obex-priv.h \
56 src/mimetype.h src/mimetype.c \70 src/mimetype.h src/mimetype.c \
57 src/service.h src/service.c71 src/service.h src/service.c \
72 src/transport.h src/transport.c \
73 src/server.h src/server.c
5874
59src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \75src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \
60 @EBOOK_LIBS@ @OPENOBEX_LIBS@ \76 @EBOOK_LIBS@ @OPENOBEX_LIBS@ \
61 @BLUEZ_LIBS@ -ldl77 @BLUEZ_LIBS@ @LIBICAL_LIBS@ -ldl
6278
63src_obexd_LDFLAGS = -Wl,--export-dynamic79src_obexd_LDFLAGS = -Wl,--export-dynamic
6480
@@ -102,6 +118,7 @@
102118
103AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \119AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \
104 @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \120 @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \
121 @LIBICAL_CFLAGS@ \
105 -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"122 -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"
106123
107INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \124INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \
@@ -111,16 +128,17 @@
111128
112EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \129EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \
113 src/obexd.service.in client/obex-client.service.in \130 src/obexd.service.in client/obex-client.service.in \
114 plugins/phonebook-dummy.c plugins/phonebook-ebook.c131 plugins/phonebook-dummy.c plugins/phonebook-ebook.c \
132 plugins/phonebook-tracker.c
115133
116DISTCHECK_CONFIGURE_FLAGS = --enable-client --enable-server134DISTCHECK_CONFIGURE_FLAGS = --enable-client --enable-server
117135
118MAINTAINERCLEANFILES = Makefile.in \136MAINTAINERCLEANFILES = Makefile.in \
119 aclocal.m4 configure config.h.in config.sub config.guess \137 aclocal.m4 configure config.h.in config.sub config.guess \
120 ltmain.sh depcomp missing install-sh mkinstalldirs138 ltmain.sh depcomp compile missing install-sh mkinstalldirs
121139
122%.service: %.service.in config.log140%.service: %.service.in config.log
123 $(AM_V_GEN)$(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@141 $(AM_V_GEN)$(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
124142
125plugins/phonebook.c: plugins/@PHONEBOOK_DRIVER@143plugins/phonebook.c: plugins/@PHONEBOOK_DRIVER@
126 $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@144 $(AM_V_GEN)$(LN_S) @abs_top_srcdir@/$< $@
127145
=== modified file 'Makefile.in'
--- Makefile.in 2010-04-27 04:17:15 +0000
+++ Makefile.in 2010-06-15 19:18:33 +0000
@@ -38,15 +38,20 @@
38host_triplet = @host@38host_triplet = @host@
39libexec_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)39libexec_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
40@SERVER_TRUE@am__append_1 = src/obexd.service.in40@SERVER_TRUE@am__append_1 = src/obexd.service.in
41@SERVER_TRUE@am__append_2 = src/obexd41@SERVER_TRUE@@USB_TRUE@am__append_2 = usb
42@SERVER_TRUE@@USB_TRUE@am__append_3 = plugins/usb.c
43@NOKIA_BACKUP_TRUE@@SERVER_TRUE@am__append_4 = backup
44@NOKIA_BACKUP_TRUE@@SERVER_TRUE@am__append_5 = plugins/nokia-backup.c
45@SERVER_TRUE@am__append_6 = src/obexd
42@SERVER_TRUE@noinst_PROGRAMS = test/obex-test$(EXEEXT)46@SERVER_TRUE@noinst_PROGRAMS = test/obex-test$(EXEEXT)
43@CLIENT_TRUE@am__append_3 = client/obex-client.service.in47@CLIENT_TRUE@am__append_7 = client/obex-client.service.in
44@CLIENT_TRUE@am__append_4 = client/obex-client48@CLIENT_TRUE@am__append_8 = client/obex-client
45subdir = .49subdir = .
46DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \50DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
47 $(srcdir)/Makefile.in $(srcdir)/config.h.in \51 $(srcdir)/Makefile.in $(srcdir)/config.h.in \
48 $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \52 $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
49 config.guess config.sub depcomp install-sh ltmain.sh missing53 compile config.guess config.sub depcomp install-sh ltmain.sh \
54 missing
50ACLOCAL_M4 = $(top_srcdir)/aclocal.m455ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
51am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \56am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
52 $(top_srcdir)/configure.ac57 $(top_srcdir)/configure.ac
@@ -108,27 +113,33 @@
108am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))113am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
109am__v_lt_0 = --silent114am__v_lt_0 = --silent
110am__src_obexd_SOURCES_DIST = gdbus/gdbus.h gdbus/mainloop.c \115am__src_obexd_SOURCES_DIST = gdbus/gdbus.h gdbus/mainloop.c \
111 gdbus/object.c gdbus/watch.c plugins/filesystem.c \116 gdbus/object.c gdbus/watch.c plugins/bluetooth.c plugins/usb.c \
112 plugins/filesystem.h plugins/opp.c plugins/ftp.c \117 plugins/filesystem.c plugins/filesystem.h \
113 plugins/pbap.c plugins/phonebook.h plugins/syncevolution.c \118 plugins/nokia-backup.c plugins/opp.c plugins/ftp.c \
114 src/main.c src/obexd.h src/plugin.h src/plugin.c src/logging.h \119 plugins/pbap.c plugins/phonebook.h plugins/vcard.h \
115 src/logging.c src/btio.h src/btio.c src/dbus.h src/manager.c \120 plugins/vcard.c plugins/syncevolution.c src/main.c src/obexd.h \
116 src/obex.h src/obex.c src/obex-priv.h src/bluetooth.h \121 src/plugin.h src/plugin.c src/logging.h src/logging.c \
117 src/bluetooth.c src/mimetype.h src/mimetype.c src/service.h \122 src/btio.h src/btio.c src/dbus.h src/manager.c src/obex.h \
118 src/service.c123 src/obex.c src/obex-priv.h src/mimetype.h src/mimetype.c \
119@SERVER_TRUE@am__objects_3 = plugins/filesystem.$(OBJEXT) \124 src/service.h src/service.c src/transport.h src/transport.c \
120@SERVER_TRUE@ plugins/opp.$(OBJEXT) plugins/ftp.$(OBJEXT) \125 src/server.h src/server.c
121@SERVER_TRUE@ plugins/pbap.$(OBJEXT) \126@SERVER_TRUE@@USB_TRUE@am__objects_3 = plugins/usb.$(OBJEXT)
127@NOKIA_BACKUP_TRUE@@SERVER_TRUE@am__objects_4 = plugins/nokia-backup.$(OBJEXT)
128@SERVER_TRUE@am__objects_5 = plugins/bluetooth.$(OBJEXT) \
129@SERVER_TRUE@ $(am__objects_3) plugins/filesystem.$(OBJEXT) \
130@SERVER_TRUE@ $(am__objects_4) plugins/opp.$(OBJEXT) \
131@SERVER_TRUE@ plugins/ftp.$(OBJEXT) plugins/pbap.$(OBJEXT) \
132@SERVER_TRUE@ plugins/vcard.$(OBJEXT) \
122@SERVER_TRUE@ plugins/syncevolution.$(OBJEXT)133@SERVER_TRUE@ plugins/syncevolution.$(OBJEXT)
123@SERVER_TRUE@am_src_obexd_OBJECTS = $(am__objects_1) $(am__objects_3) \134@SERVER_TRUE@am_src_obexd_OBJECTS = $(am__objects_1) $(am__objects_5) \
124@SERVER_TRUE@ src/main.$(OBJEXT) src/plugin.$(OBJEXT) \135@SERVER_TRUE@ src/main.$(OBJEXT) src/plugin.$(OBJEXT) \
125@SERVER_TRUE@ src/logging.$(OBJEXT) src/btio.$(OBJEXT) \136@SERVER_TRUE@ src/logging.$(OBJEXT) src/btio.$(OBJEXT) \
126@SERVER_TRUE@ src/manager.$(OBJEXT) src/obex.$(OBJEXT) \137@SERVER_TRUE@ src/manager.$(OBJEXT) src/obex.$(OBJEXT) \
127@SERVER_TRUE@ src/bluetooth.$(OBJEXT) src/mimetype.$(OBJEXT) \138@SERVER_TRUE@ src/mimetype.$(OBJEXT) src/service.$(OBJEXT) \
128@SERVER_TRUE@ src/service.$(OBJEXT)139@SERVER_TRUE@ src/transport.$(OBJEXT) src/server.$(OBJEXT)
129@SERVER_TRUE@am__objects_4 = plugins/phonebook.$(OBJEXT)140@SERVER_TRUE@am__objects_6 = plugins/phonebook.$(OBJEXT)
130@SERVER_TRUE@am__objects_5 = $(am__objects_4)141@SERVER_TRUE@am__objects_7 = $(am__objects_6)
131@SERVER_TRUE@nodist_src_obexd_OBJECTS = $(am__objects_5)142@SERVER_TRUE@nodist_src_obexd_OBJECTS = $(am__objects_7)
132src_obexd_OBJECTS = $(am_src_obexd_OBJECTS) \143src_obexd_OBJECTS = $(am_src_obexd_OBJECTS) \
133 $(nodist_src_obexd_OBJECTS)144 $(nodist_src_obexd_OBJECTS)
134src_obexd_DEPENDENCIES =145src_obexd_DEPENDENCIES =
@@ -230,6 +241,8 @@
230INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@241INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
231LD = @LD@242LD = @LD@
232LDFLAGS = @LDFLAGS@243LDFLAGS = @LDFLAGS@
244LIBICAL_CFLAGS = @LIBICAL_CFLAGS@
245LIBICAL_LIBS = @LIBICAL_LIBS@
233LIBOBJS = @LIBOBJS@246LIBOBJS = @LIBOBJS@
234LIBS = @LIBS@247LIBS = @LIBS@
235LIBTOOL = @LIBTOOL@248LIBTOOL = @LIBTOOL@
@@ -316,7 +329,7 @@
316top_srcdir = @top_srcdir@329top_srcdir = @top_srcdir@
317AM_MAKEFLAGS = --no-print-directory330AM_MAKEFLAGS = --no-print-directory
318servicedir = $(datarootdir)/dbus-1/services331servicedir = $(datarootdir)/dbus-1/services
319service_in_files = $(am__append_1) $(am__append_3)332service_in_files = $(am__append_1) $(am__append_7)
320doc_files = doc/obexd-api.txt doc/agent-api.txt doc/client-api.txt333doc_files = doc/obexd-api.txt doc/agent-api.txt doc/client-api.txt
321test_files = test/simple-agent test/send-files \334test_files = test/simple-agent test/send-files \
322 test/pull-business-card test/exchange-business-cards \335 test/pull-business-card test/exchange-business-cards \
@@ -329,23 +342,28 @@
329 gwobex/utils.h gwobex/utils.c gwobex/log.h342 gwobex/utils.h gwobex/utils.c gwobex/log.h
330343
331@SERVER_TRUE@confdir = $(sysconfdir)/obex344@SERVER_TRUE@confdir = $(sysconfdir)/obex
332@SERVER_TRUE@builtin_modules = filesystem opp ftp pbap syncevolution345@SERVER_TRUE@builtin_modules = bluetooth $(am__append_2) filesystem \
333@SERVER_TRUE@builtin_sources = plugins/filesystem.c \346@SERVER_TRUE@ $(am__append_4) opp ftp pbap syncevolution
334@SERVER_TRUE@ plugins/filesystem.h plugins/opp.c plugins/ftp.c \347@SERVER_TRUE@builtin_sources = plugins/bluetooth.c $(am__append_3) \
348@SERVER_TRUE@ plugins/filesystem.c plugins/filesystem.h \
349@SERVER_TRUE@ $(am__append_5) plugins/opp.c plugins/ftp.c \
335@SERVER_TRUE@ plugins/pbap.c plugins/phonebook.h \350@SERVER_TRUE@ plugins/pbap.c plugins/phonebook.h \
351@SERVER_TRUE@ plugins/vcard.h plugins/vcard.c \
336@SERVER_TRUE@ plugins/syncevolution.c352@SERVER_TRUE@ plugins/syncevolution.c
337@SERVER_TRUE@builtin_nodist = plugins/phonebook.c353@SERVER_TRUE@builtin_nodist = plugins/phonebook.c
338@SERVER_TRUE@src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) \354@SERVER_TRUE@src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) \
339@SERVER_TRUE@ src/main.c src/obexd.h src/plugin.h src/plugin.c \355@SERVER_TRUE@ src/main.c src/obexd.h src/plugin.h src/plugin.c \
340@SERVER_TRUE@ src/logging.h src/logging.c src/btio.h src/btio.c \356@SERVER_TRUE@ src/logging.h src/logging.c src/btio.h src/btio.c \
341@SERVER_TRUE@ src/dbus.h src/manager.c src/obex.h src/obex.c \357@SERVER_TRUE@ src/dbus.h src/manager.c src/obex.h src/obex.c \
342@SERVER_TRUE@ src/obex-priv.h src/bluetooth.h src/bluetooth.c \358@SERVER_TRUE@ src/obex-priv.h \
343@SERVER_TRUE@ src/mimetype.h src/mimetype.c \359@SERVER_TRUE@ src/mimetype.h src/mimetype.c \
344@SERVER_TRUE@ src/service.h src/service.c360@SERVER_TRUE@ src/service.h src/service.c \
361@SERVER_TRUE@ src/transport.h src/transport.c \
362@SERVER_TRUE@ src/server.h src/server.c
345363
346@SERVER_TRUE@src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \364@SERVER_TRUE@src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \
347@SERVER_TRUE@ @EBOOK_LIBS@ @OPENOBEX_LIBS@ \365@SERVER_TRUE@ @EBOOK_LIBS@ @OPENOBEX_LIBS@ \
348@SERVER_TRUE@ @BLUEZ_LIBS@ -ldl366@SERVER_TRUE@ @BLUEZ_LIBS@ @LIBICAL_LIBS@ -ldl
349367
350@SERVER_TRUE@src_obexd_LDFLAGS = -Wl,--export-dynamic368@SERVER_TRUE@src_obexd_LDFLAGS = -Wl,--export-dynamic
351@SERVER_TRUE@builtin_files = src/builtin.h $(builtin_nodist)369@SERVER_TRUE@builtin_files = src/builtin.h $(builtin_nodist)
@@ -365,6 +383,7 @@
365service_DATA = $(service_in_files:.service.in=.service)383service_DATA = $(service_in_files:.service.in=.service)
366AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \384AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \
367 @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \385 @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \
386 @LIBICAL_CFLAGS@ \
368 -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"387 -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"
369388
370INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \389INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \
@@ -373,12 +392,13 @@
373CLEANFILES = $(service_DATA) $(builtin_files)392CLEANFILES = $(service_DATA) $(builtin_files)
374EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \393EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \
375 src/obexd.service.in client/obex-client.service.in \394 src/obexd.service.in client/obex-client.service.in \
376 plugins/phonebook-dummy.c plugins/phonebook-ebook.c395 plugins/phonebook-dummy.c plugins/phonebook-ebook.c \
396 plugins/phonebook-tracker.c
377397
378DISTCHECK_CONFIGURE_FLAGS = --enable-client --enable-server398DISTCHECK_CONFIGURE_FLAGS = --enable-client --enable-server
379MAINTAINERCLEANFILES = Makefile.in \399MAINTAINERCLEANFILES = Makefile.in \
380 aclocal.m4 configure config.h.in config.sub config.guess \400 aclocal.m4 configure config.h.in config.sub config.guess \
381 ltmain.sh depcomp missing install-sh mkinstalldirs401 ltmain.sh depcomp compile missing install-sh mkinstalldirs
382402
383all: config.h403all: config.h
384 $(MAKE) $(AM_MAKEFLAGS) all-am404 $(MAKE) $(AM_MAKEFLAGS) all-am
@@ -578,14 +598,22 @@
578plugins/$(DEPDIR)/$(am__dirstamp):598plugins/$(DEPDIR)/$(am__dirstamp):
579 @$(MKDIR_P) plugins/$(DEPDIR)599 @$(MKDIR_P) plugins/$(DEPDIR)
580 @: > plugins/$(DEPDIR)/$(am__dirstamp)600 @: > plugins/$(DEPDIR)/$(am__dirstamp)
601plugins/bluetooth.$(OBJEXT): plugins/$(am__dirstamp) \
602 plugins/$(DEPDIR)/$(am__dirstamp)
603plugins/usb.$(OBJEXT): plugins/$(am__dirstamp) \
604 plugins/$(DEPDIR)/$(am__dirstamp)
581plugins/filesystem.$(OBJEXT): plugins/$(am__dirstamp) \605plugins/filesystem.$(OBJEXT): plugins/$(am__dirstamp) \
582 plugins/$(DEPDIR)/$(am__dirstamp)606 plugins/$(DEPDIR)/$(am__dirstamp)
607plugins/nokia-backup.$(OBJEXT): plugins/$(am__dirstamp) \
608 plugins/$(DEPDIR)/$(am__dirstamp)
583plugins/opp.$(OBJEXT): plugins/$(am__dirstamp) \609plugins/opp.$(OBJEXT): plugins/$(am__dirstamp) \
584 plugins/$(DEPDIR)/$(am__dirstamp)610 plugins/$(DEPDIR)/$(am__dirstamp)
585plugins/ftp.$(OBJEXT): plugins/$(am__dirstamp) \611plugins/ftp.$(OBJEXT): plugins/$(am__dirstamp) \
586 plugins/$(DEPDIR)/$(am__dirstamp)612 plugins/$(DEPDIR)/$(am__dirstamp)
587plugins/pbap.$(OBJEXT): plugins/$(am__dirstamp) \613plugins/pbap.$(OBJEXT): plugins/$(am__dirstamp) \
588 plugins/$(DEPDIR)/$(am__dirstamp)614 plugins/$(DEPDIR)/$(am__dirstamp)
615plugins/vcard.$(OBJEXT): plugins/$(am__dirstamp) \
616 plugins/$(DEPDIR)/$(am__dirstamp)
589plugins/syncevolution.$(OBJEXT): plugins/$(am__dirstamp) \617plugins/syncevolution.$(OBJEXT): plugins/$(am__dirstamp) \
590 plugins/$(DEPDIR)/$(am__dirstamp)618 plugins/$(DEPDIR)/$(am__dirstamp)
591src/main.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)619src/main.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
@@ -595,12 +623,14 @@
595src/manager.$(OBJEXT): src/$(am__dirstamp) \623src/manager.$(OBJEXT): src/$(am__dirstamp) \
596 src/$(DEPDIR)/$(am__dirstamp)624 src/$(DEPDIR)/$(am__dirstamp)
597src/obex.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)625src/obex.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
598src/bluetooth.$(OBJEXT): src/$(am__dirstamp) \
599 src/$(DEPDIR)/$(am__dirstamp)
600src/mimetype.$(OBJEXT): src/$(am__dirstamp) \626src/mimetype.$(OBJEXT): src/$(am__dirstamp) \
601 src/$(DEPDIR)/$(am__dirstamp)627 src/$(DEPDIR)/$(am__dirstamp)
602src/service.$(OBJEXT): src/$(am__dirstamp) \628src/service.$(OBJEXT): src/$(am__dirstamp) \
603 src/$(DEPDIR)/$(am__dirstamp)629 src/$(DEPDIR)/$(am__dirstamp)
630src/transport.$(OBJEXT): src/$(am__dirstamp) \
631 src/$(DEPDIR)/$(am__dirstamp)
632src/server.$(OBJEXT): src/$(am__dirstamp) \
633 src/$(DEPDIR)/$(am__dirstamp)
604plugins/phonebook.$(OBJEXT): plugins/$(am__dirstamp) \634plugins/phonebook.$(OBJEXT): plugins/$(am__dirstamp) \
605 plugins/$(DEPDIR)/$(am__dirstamp)635 plugins/$(DEPDIR)/$(am__dirstamp)
606src/obexd$(EXEEXT): $(src_obexd_OBJECTS) $(src_obexd_DEPENDENCIES) src/$(am__dirstamp)636src/obexd$(EXEEXT): $(src_obexd_OBJECTS) $(src_obexd_DEPENDENCIES) src/$(am__dirstamp)
@@ -632,13 +662,16 @@
632 -rm -f gwobex/obex-priv.$(OBJEXT)662 -rm -f gwobex/obex-priv.$(OBJEXT)
633 -rm -f gwobex/obex-xfer.$(OBJEXT)663 -rm -f gwobex/obex-xfer.$(OBJEXT)
634 -rm -f gwobex/utils.$(OBJEXT)664 -rm -f gwobex/utils.$(OBJEXT)
665 -rm -f plugins/bluetooth.$(OBJEXT)
635 -rm -f plugins/filesystem.$(OBJEXT)666 -rm -f plugins/filesystem.$(OBJEXT)
636 -rm -f plugins/ftp.$(OBJEXT)667 -rm -f plugins/ftp.$(OBJEXT)
668 -rm -f plugins/nokia-backup.$(OBJEXT)
637 -rm -f plugins/opp.$(OBJEXT)669 -rm -f plugins/opp.$(OBJEXT)
638 -rm -f plugins/pbap.$(OBJEXT)670 -rm -f plugins/pbap.$(OBJEXT)
639 -rm -f plugins/phonebook.$(OBJEXT)671 -rm -f plugins/phonebook.$(OBJEXT)
640 -rm -f plugins/syncevolution.$(OBJEXT)672 -rm -f plugins/syncevolution.$(OBJEXT)
641 -rm -f src/bluetooth.$(OBJEXT)673 -rm -f plugins/usb.$(OBJEXT)
674 -rm -f plugins/vcard.$(OBJEXT)
642 -rm -f src/btio.$(OBJEXT)675 -rm -f src/btio.$(OBJEXT)
643 -rm -f src/logging.$(OBJEXT)676 -rm -f src/logging.$(OBJEXT)
644 -rm -f src/main.$(OBJEXT)677 -rm -f src/main.$(OBJEXT)
@@ -646,7 +679,9 @@
646 -rm -f src/mimetype.$(OBJEXT)679 -rm -f src/mimetype.$(OBJEXT)
647 -rm -f src/obex.$(OBJEXT)680 -rm -f src/obex.$(OBJEXT)
648 -rm -f src/plugin.$(OBJEXT)681 -rm -f src/plugin.$(OBJEXT)
682 -rm -f src/server.$(OBJEXT)
649 -rm -f src/service.$(OBJEXT)683 -rm -f src/service.$(OBJEXT)
684 -rm -f src/transport.$(OBJEXT)
650 -rm -f test/main.$(OBJEXT)685 -rm -f test/main.$(OBJEXT)
651686
652distclean-compile:687distclean-compile:
@@ -664,13 +699,16 @@
664@AMDEP_TRUE@@am__include@ @am__quote@gwobex/$(DEPDIR)/obex-priv.Po@am__quote@699@AMDEP_TRUE@@am__include@ @am__quote@gwobex/$(DEPDIR)/obex-priv.Po@am__quote@
665@AMDEP_TRUE@@am__include@ @am__quote@gwobex/$(DEPDIR)/obex-xfer.Po@am__quote@700@AMDEP_TRUE@@am__include@ @am__quote@gwobex/$(DEPDIR)/obex-xfer.Po@am__quote@
666@AMDEP_TRUE@@am__include@ @am__quote@gwobex/$(DEPDIR)/utils.Po@am__quote@701@AMDEP_TRUE@@am__include@ @am__quote@gwobex/$(DEPDIR)/utils.Po@am__quote@
702@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/bluetooth.Po@am__quote@
667@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/filesystem.Po@am__quote@703@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/filesystem.Po@am__quote@
668@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/ftp.Po@am__quote@704@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/ftp.Po@am__quote@
705@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/nokia-backup.Po@am__quote@
669@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/opp.Po@am__quote@706@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/opp.Po@am__quote@
670@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/pbap.Po@am__quote@707@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/pbap.Po@am__quote@
671@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/phonebook.Po@am__quote@708@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/phonebook.Po@am__quote@
672@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/syncevolution.Po@am__quote@709@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/syncevolution.Po@am__quote@
673@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bluetooth.Po@am__quote@710@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/usb.Po@am__quote@
711@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/vcard.Po@am__quote@
674@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/btio.Po@am__quote@712@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/btio.Po@am__quote@
675@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logging.Po@am__quote@713@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logging.Po@am__quote@
676@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/main.Po@am__quote@714@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/main.Po@am__quote@
@@ -678,7 +716,9 @@
678@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mimetype.Po@am__quote@716@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mimetype.Po@am__quote@
679@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/obex.Po@am__quote@717@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/obex.Po@am__quote@
680@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/plugin.Po@am__quote@718@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/plugin.Po@am__quote@
719@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/server.Po@am__quote@
681@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/service.Po@am__quote@720@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/service.Po@am__quote@
721@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/transport.Po@am__quote@
682@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/main.Po@am__quote@722@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/main.Po@am__quote@
683723
684.c.o:724.c.o:
@@ -1092,7 +1132,7 @@
1092 $(AM_V_GEN)$(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@1132 $(AM_V_GEN)$(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
10931133
1094plugins/phonebook.c: plugins/@PHONEBOOK_DRIVER@1134plugins/phonebook.c: plugins/@PHONEBOOK_DRIVER@
1095 $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@1135 $(AM_V_GEN)$(LN_S) @abs_top_srcdir@/$< $@
10961136
1097# Tell versions [3.59,3.63) of GNU make to not export all variables.1137# Tell versions [3.59,3.63) of GNU make to not export all variables.
1098# Otherwise a system limit (for SysV at least) may be exceeded.1138# Otherwise a system limit (for SysV at least) may be exceeded.
10991139
=== modified file 'aclocal.m4'
--- aclocal.m4 2010-03-15 20:43:06 +0000
+++ aclocal.m4 2010-06-15 19:18:33 +0000
@@ -8796,6 +8796,41 @@
8796rm -f confinc confmf8796rm -f confinc confmf
8797])8797])
87988798
8799# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
8800# Free Software Foundation, Inc.
8801#
8802# This file is free software; the Free Software Foundation
8803# gives unlimited permission to copy and/or distribute it,
8804# with or without modifications, as long as this notice is preserved.
8805
8806# serial 6
8807
8808# AM_PROG_CC_C_O
8809# --------------
8810# Like AC_PROG_CC_C_O, but changed for automake.
8811AC_DEFUN([AM_PROG_CC_C_O],
8812[AC_REQUIRE([AC_PROG_CC_C_O])dnl
8813AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
8814AC_REQUIRE_AUX_FILE([compile])dnl
8815# FIXME: we rely on the cache variable name because
8816# there is no other way.
8817set dummy $CC
8818am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
8819eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
8820if test "$am_t" != yes; then
8821 # Losing compiler, so override with the script.
8822 # FIXME: It is wrong to rewrite CC.
8823 # But if we don't then we get into trouble of one sort or another.
8824 # A longer-term fix would be to have automake use am__CC in this case,
8825 # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
8826 CC="$am_aux_dir/compile $CC"
8827fi
8828dnl Make sure AC_PROG_CC is never called again, or it will override our
8829dnl setting of CC.
8830m4_define([AC_PROG_CC],
8831 [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
8832])
8833
8799# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-8834# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
88008835
8801# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 20088836# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
88028837
=== modified file 'client/main.c'
--- client/main.c 2010-04-27 04:17:15 +0000
+++ client/main.c 2010-06-15 19:18:33 +0000
@@ -48,6 +48,7 @@
48 DBusMessage *message;48 DBusMessage *message;
49 gchar *sender;49 gchar *sender;
50 gchar *agent;50 gchar *agent;
51 char *filename;
51 GPtrArray *files;52 GPtrArray *files;
52};53};
5354
@@ -232,12 +233,25 @@
232 void *user_data)233 void *user_data)
233{234{
234 struct send_data *data = user_data;235 struct send_data *data = user_data;
236 struct transfer_data *transfer = session->pending->data;
237
238 if (transfer->err != 0) {
239 DBusMessage *error = g_dbus_create_error(data->message,
240 "org.openobex.Error.Failed",
241 transfer->err > 0 ?
242 OBEX_ResponseToString(transfer->err) :
243 strerror(-transfer->err));
244 g_dbus_send_message(data->connection, error);
245 goto done;
246 }
235247
236 g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);248 g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
237249
250done:
238 shutdown_session(session);251 shutdown_session(session);
239 dbus_message_unref(data->message);252 dbus_message_unref(data->message);
240 dbus_connection_unref(data->connection);253 dbus_connection_unref(data->connection);
254 g_free(data->filename);
241 g_free(data->sender);255 g_free(data->sender);
242 g_free(data);256 g_free(data);
243}257}
@@ -256,9 +270,8 @@
256 }270 }
257271
258 session_set_owner(session, data->sender, owner_exit);272 session_set_owner(session, data->sender, owner_exit);
259 g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
260273
261 session_pull(session, "text/x-vcard", "/tmp/x.vcf",274 session_pull(session, "text/x-vcard", data->filename,
262 pull_complete_callback, data);275 pull_complete_callback, data);
263276
264 return;277 return;
@@ -266,6 +279,7 @@
266done:279done:
267 dbus_message_unref(data->message);280 dbus_message_unref(data->message);
268 dbus_connection_unref(data->connection);281 dbus_connection_unref(data->connection);
282 g_free(data->filename);
269 g_free(data->sender);283 g_free(data->sender);
270 g_free(data);284 g_free(data);
271}285}
@@ -277,6 +291,7 @@
277 struct session_data *session;291 struct session_data *session;
278 struct send_data *data;292 struct send_data *data;
279 const char *source = NULL, *dest = NULL, *target = NULL;293 const char *source = NULL, *dest = NULL, *target = NULL;
294 const char *name = NULL;
280 uint8_t channel = 0;295 uint8_t channel = 0;
281296
282 dbus_message_iter_init(message, &iter);297 dbus_message_iter_init(message, &iter);
@@ -287,6 +302,14 @@
287 return g_dbus_create_error(message,302 return g_dbus_create_error(message,
288 "org.openobex.Error.InvalidArguments", NULL);303 "org.openobex.Error.InvalidArguments", NULL);
289304
305 dbus_message_iter_next(&iter);
306
307 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
308 return g_dbus_create_error(message,
309 "org.openobex.Error.InvalidArguments", NULL);
310
311 dbus_message_iter_get_basic(&iter, &name);
312
290 data = g_try_malloc0(sizeof(*data));313 data = g_try_malloc0(sizeof(*data));
291 if (data == NULL)314 if (data == NULL)
292 return g_dbus_create_error(message,315 return g_dbus_create_error(message,
@@ -295,6 +318,7 @@
295 data->connection = dbus_connection_ref(connection);318 data->connection = dbus_connection_ref(connection);
296 data->message = dbus_message_ref(message);319 data->message = dbus_message_ref(message);
297 data->sender = g_strdup(dbus_message_get_sender(message));320 data->sender = g_strdup(dbus_message_get_sender(message));
321 data->filename = g_strdup(name);
298322
299 session = session_create(source, dest, "OPP", channel,323 session = session_create(source, dest, "OPP", channel,
300 pull_session_callback, data);324 pull_session_callback, data);
@@ -306,6 +330,7 @@
306 dbus_message_unref(data->message);330 dbus_message_unref(data->message);
307 dbus_connection_unref(data->connection);331 dbus_connection_unref(data->connection);
308 g_free(data->sender);332 g_free(data->sender);
333 g_free(data->filename);
309 g_free(data);334 g_free(data);
310335
311 return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);336 return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
@@ -379,7 +404,7 @@
379 const gchar *sender, *path;404 const gchar *sender, *path;
380405
381 if (dbus_message_get_args(message, NULL,406 if (dbus_message_get_args(message, NULL,
382 DBUS_TYPE_STRING, &path,407 DBUS_TYPE_OBJECT_PATH, &path,
383 DBUS_TYPE_INVALID) == FALSE)408 DBUS_TYPE_INVALID) == FALSE)
384 return g_dbus_create_error(message,409 return g_dbus_create_error(message,
385 "org.openobex.Error.InvalidArguments", NULL);410 "org.openobex.Error.InvalidArguments", NULL);
386411
=== modified file 'client/session.c'
--- client/session.c 2010-04-27 04:17:15 +0000
+++ client/session.c 2010-06-15 19:18:33 +0000
@@ -1278,7 +1278,7 @@
1278 if (session->obex == NULL)1278 if (session->obex == NULL)
1279 return -ENOTCONN;1279 return -ENOTCONN;
12801280
1281 transfer = transfer_register(session, NULL, NULL, type, NULL);1281 transfer = transfer_register(session, NULL, filename, type, NULL);
1282 if (transfer == NULL) {1282 if (transfer == NULL) {
1283 return -EIO;1283 return -EIO;
1284 }1284 }
12851285
=== modified file 'client/transfer.c'
--- client/transfer.c 2010-04-27 04:17:15 +0000
+++ client/transfer.c 2010-06-15 19:18:33 +0000
@@ -406,17 +406,20 @@
406 if (transfer->xfer != NULL)406 if (transfer->xfer != NULL)
407 return -EALREADY;407 return -EALREADY;
408408
409 if (transfer->type == NULL) {409 if (g_strcmp0(transfer->type, "x-bt/vcard-listing") == 0 ||
410 g_strcmp0(transfer->type, "x-obex/folder-listing") == 0)
411 cb = get_xfer_listing_progress;
412 else {
410 int fd = open(transfer->name ? : transfer->filename,413 int fd = open(transfer->name ? : transfer->filename,
411 O_WRONLY | O_CREAT, 0600);414 O_WRONLY | O_CREAT, 0600);
415
412 if (transfer->fd < 0) {416 if (transfer->fd < 0) {
413 error("open(): %s(%d)", strerror(errno), errno);417 error("open(): %s(%d)", strerror(errno), errno);
414 return -errno;418 return -errno;
415 }419 }
416 transfer->fd = fd;420 transfer->fd = fd;
417 cb = get_xfer_progress;421 cb = get_xfer_progress;
418 } else422 }
419 cb = get_xfer_listing_progress;
420423
421 if (transfer->params != NULL)424 if (transfer->params != NULL)
422 transfer->xfer = gw_obex_get_async_with_apparam(session->obex,425 transfer->xfer = gw_obex_get_async_with_apparam(session->obex,
423426
=== added file 'compile'
--- compile 1970-01-01 00:00:00 +0000
+++ compile 2010-06-15 19:18:33 +0000
@@ -0,0 +1,143 @@
1#! /bin/sh
2# Wrapper for compilers which do not understand `-c -o'.
3
4scriptversion=2009-10-06.20; # UTC
5
6# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
7# Foundation, Inc.
8# Written by Tom Tromey <tromey@cygnus.com>.
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2, or (at your option)
13# any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23# As a special exception to the GNU General Public License, if you
24# distribute this file as part of a program that contains a
25# configuration script generated by Autoconf, you may include it under
26# the same distribution terms that you use for the rest of that program.
27
28# This file is maintained in Automake, please report
29# bugs to <bug-automake@gnu.org> or send patches to
30# <automake-patches@gnu.org>.
31
32case $1 in
33 '')
34 echo "$0: No command. Try \`$0 --help' for more information." 1>&2
35 exit 1;
36 ;;
37 -h | --h*)
38 cat <<\EOF
39Usage: compile [--help] [--version] PROGRAM [ARGS]
40
41Wrapper for compilers which do not understand `-c -o'.
42Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
43arguments, and rename the output as expected.
44
45If you are trying to build a whole package this is not the
46right script to run: please start by reading the file `INSTALL'.
47
48Report bugs to <bug-automake@gnu.org>.
49EOF
50 exit $?
51 ;;
52 -v | --v*)
53 echo "compile $scriptversion"
54 exit $?
55 ;;
56esac
57
58ofile=
59cfile=
60eat=
61
62for arg
63do
64 if test -n "$eat"; then
65 eat=
66 else
67 case $1 in
68 -o)
69 # configure might choose to run compile as `compile cc -o foo foo.c'.
70 # So we strip `-o arg' only if arg is an object.
71 eat=1
72 case $2 in
73 *.o | *.obj)
74 ofile=$2
75 ;;
76 *)
77 set x "$@" -o "$2"
78 shift
79 ;;
80 esac
81 ;;
82 *.c)
83 cfile=$1
84 set x "$@" "$1"
85 shift
86 ;;
87 *)
88 set x "$@" "$1"
89 shift
90 ;;
91 esac
92 fi
93 shift
94done
95
96if test -z "$ofile" || test -z "$cfile"; then
97 # If no `-o' option was seen then we might have been invoked from a
98 # pattern rule where we don't need one. That is ok -- this is a
99 # normal compilation that the losing compiler can handle. If no
100 # `.c' file was seen then we are probably linking. That is also
101 # ok.
102 exec "$@"
103fi
104
105# Name of file we expect compiler to create.
106cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
107
108# Create the lock directory.
109# Note: use `[/\\:.-]' here to ensure that we don't use the same name
110# that we are using for the .o file. Also, base the name on the expected
111# object file name, since that is what matters with a parallel build.
112lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
113while true; do
114 if mkdir "$lockdir" >/dev/null 2>&1; then
115 break
116 fi
117 sleep 1
118done
119# FIXME: race condition here if user kills between mkdir and trap.
120trap "rmdir '$lockdir'; exit 1" 1 2 15
121
122# Run the compile.
123"$@"
124ret=$?
125
126if test -f "$cofile"; then
127 test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
128elif test -f "${cofile}bj"; then
129 test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
130fi
131
132rmdir "$lockdir"
133exit $ret
134
135# Local Variables:
136# mode: shell-script
137# sh-indentation: 2
138# eval: (add-hook 'write-file-hooks 'time-stamp)
139# time-stamp-start: "scriptversion="
140# time-stamp-format: "%:y-%02m-%02d.%02H"
141# time-stamp-time-zone: "UTC"
142# time-stamp-end: "; # UTC"
143# End:
0144
=== modified file 'config.h.in'
--- config.h.in 2010-03-15 20:43:06 +0000
+++ config.h.in 2010-06-15 19:18:33 +0000
@@ -52,6 +52,9 @@
52/* Define if threading support is required */52/* Define if threading support is required */
53#undef NEED_THREADS53#undef NEED_THREADS
5454
55/* Define to 1 if your C compiler doesn't accept -c and -o together. */
56#undef NO_MINUS_C_MINUS_O
57
55/* Name of package */58/* Name of package */
56#undef PACKAGE59#undef PACKAGE
5760
5861
=== modified file 'configure'
--- configure 2010-04-27 04:17:15 +0000
+++ configure 2010-06-15 19:18:33 +0000
@@ -1,6 +1,6 @@
1#! /bin/sh1#! /bin/sh
2# Guess values for system-dependent variables and create Makefiles.2# Guess values for system-dependent variables and create Makefiles.
3# Generated by GNU Autoconf 2.63 for obexd 0.23.3# Generated by GNU Autoconf 2.63 for obexd 0.28.
4#4#
5# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,5# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
6# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.6# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@
743# Identity of this package.743# Identity of this package.
744PACKAGE_NAME='obexd'744PACKAGE_NAME='obexd'
745PACKAGE_TARNAME='obexd'745PACKAGE_TARNAME='obexd'
746PACKAGE_VERSION='0.23'746PACKAGE_VERSION='0.28'
747PACKAGE_STRING='obexd 0.23'747PACKAGE_STRING='obexd 0.28'
748PACKAGE_BUGREPORT=''748PACKAGE_BUGREPORT=''
749749
750ac_default_prefix=/usr/local750ac_default_prefix=/usr/local
@@ -790,6 +790,10 @@
790LIBOBJS790LIBOBJS
791CLIENT_FALSE791CLIENT_FALSE
792CLIENT_TRUE792CLIENT_TRUE
793NOKIA_BACKUP_FALSE
794NOKIA_BACKUP_TRUE
795USB_FALSE
796USB_TRUE
793SERVER_FALSE797SERVER_FALSE
794SERVER_TRUE798SERVER_TRUE
795PHONEBOOK_DRIVER799PHONEBOOK_DRIVER
@@ -797,6 +801,8 @@
797GTHREAD_CFLAGS801GTHREAD_CFLAGS
798EBOOK_LIBS802EBOOK_LIBS
799EBOOK_CFLAGS803EBOOK_CFLAGS
804LIBICAL_LIBS
805LIBICAL_CFLAGS
800BLUEZ_LIBS806BLUEZ_LIBS
801BLUEZ_CFLAGS807BLUEZ_CFLAGS
802OPENOBEX_LIBS808OPENOBEX_LIBS
@@ -931,6 +937,8 @@
931enable_debug937enable_debug
932with_phonebook938with_phonebook
933enable_server939enable_server
940enable_usb
941enable_nokia_backup
934enable_client942enable_client
935'943'
936 ac_precious_vars='build_alias944 ac_precious_vars='build_alias
@@ -951,6 +959,8 @@
951OPENOBEX_LIBS959OPENOBEX_LIBS
952BLUEZ_CFLAGS960BLUEZ_CFLAGS
953BLUEZ_LIBS961BLUEZ_LIBS
962LIBICAL_CFLAGS
963LIBICAL_LIBS
954EBOOK_CFLAGS964EBOOK_CFLAGS
955EBOOK_LIBS965EBOOK_LIBS
956GTHREAD_CFLAGS966GTHREAD_CFLAGS
@@ -1507,7 +1517,7 @@
1507 # Omit some internal or obsolete options to make the list less imposing.1517 # Omit some internal or obsolete options to make the list less imposing.
1508 # This message is too long to be a string in the A/UX 3.1 sh.1518 # This message is too long to be a string in the A/UX 3.1 sh.
1509 cat <<_ACEOF1519 cat <<_ACEOF
1510\`configure' configures obexd 0.23 to adapt to many kinds of systems.1520\`configure' configures obexd 0.28 to adapt to many kinds of systems.
15111521
1512Usage: $0 [OPTION]... [VAR=VALUE]...1522Usage: $0 [OPTION]... [VAR=VALUE]...
15131523
@@ -1577,7 +1587,7 @@
15771587
1578if test -n "$ac_init_help"; then1588if test -n "$ac_init_help"; then
1579 case $ac_init_help in1589 case $ac_init_help in
1580 short | recursive ) echo "Configuration of obexd 0.23:";;1590 short | recursive ) echo "Configuration of obexd 0.28:";;
1581 esac1591 esac
1582 cat <<\_ACEOF1592 cat <<\_ACEOF
15831593
@@ -1599,6 +1609,8 @@
1599 --disable-optimization disable code optimization through compiler1609 --disable-optimization disable code optimization through compiler
1600 --enable-debug enable compiling with debugging information1610 --enable-debug enable compiling with debugging information
1601 --disable-server disable compilation of OBEX server1611 --disable-server disable compilation of OBEX server
1612 --enable-usb enable usb plugin
1613 --enable-nokia-backup enable nokia-backup plugin
1602 --disable-client disable compilation of OBEX client1614 --disable-client disable compilation of OBEX client
16031615
1604Optional Packages:1616Optional Packages:
@@ -1630,6 +1642,10 @@
1630 BLUEZ_CFLAGS1642 BLUEZ_CFLAGS
1631 C compiler flags for BLUEZ, overriding pkg-config1643 C compiler flags for BLUEZ, overriding pkg-config
1632 BLUEZ_LIBS linker flags for BLUEZ, overriding pkg-config1644 BLUEZ_LIBS linker flags for BLUEZ, overriding pkg-config
1645 LIBICAL_CFLAGS
1646 C compiler flags for LIBICAL, overriding pkg-config
1647 LIBICAL_LIBS
1648 linker flags for LIBICAL, overriding pkg-config
1633 EBOOK_CFLAGS1649 EBOOK_CFLAGS
1634 C compiler flags for EBOOK, overriding pkg-config1650 C compiler flags for EBOOK, overriding pkg-config
1635 EBOOK_LIBS linker flags for EBOOK, overriding pkg-config1651 EBOOK_LIBS linker flags for EBOOK, overriding pkg-config
@@ -1703,7 +1719,7 @@
1703test -n "$ac_init_help" && exit $ac_status1719test -n "$ac_init_help" && exit $ac_status
1704if $ac_init_version; then1720if $ac_init_version; then
1705 cat <<\_ACEOF1721 cat <<\_ACEOF
1706obexd configure 0.231722obexd configure 0.28
1707generated by GNU Autoconf 2.631723generated by GNU Autoconf 2.63
17081724
1709Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,1725Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1717,7 +1733,7 @@
1717This file contains any messages produced by compilers while1733This file contains any messages produced by compilers while
1718running configure, to aid debugging if configure makes a mistake.1734running configure, to aid debugging if configure makes a mistake.
17191735
1720It was created by obexd $as_me 0.23, which was1736It was created by obexd $as_me 0.28, which was
1721generated by GNU Autoconf 2.63. Invocation command line was1737generated by GNU Autoconf 2.63. Invocation command line was
17221738
1723 $ $0 $@1739 $ $0 $@
@@ -2567,7 +2583,7 @@
25672583
2568# Define the identity of the package.2584# Define the identity of the package.
2569 PACKAGE='obexd'2585 PACKAGE='obexd'
2570 VERSION='0.23'2586 VERSION='0.28'
25712587
25722588
2573cat >>confdefs.h <<_ACEOF2589cat >>confdefs.h <<_ACEOF
@@ -3811,6 +3827,138 @@
3811fi3827fi
38123828
38133829
3830if test "x$CC" != xcc; then
3831 { $as_echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5
3832$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
3833else
3834 { $as_echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5
3835$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
3836fi
3837set dummy $CC; ac_cc=`$as_echo "$2" |
3838 sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
3839if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then
3840 $as_echo_n "(cached) " >&6
3841else
3842 cat >conftest.$ac_ext <<_ACEOF
3843/* confdefs.h. */
3844_ACEOF
3845cat confdefs.h >>conftest.$ac_ext
3846cat >>conftest.$ac_ext <<_ACEOF
3847/* end confdefs.h. */
3848
3849int
3850main ()
3851{
3852
3853 ;
3854 return 0;
3855}
3856_ACEOF
3857# Make sure it works both with $CC and with simple cc.
3858# We do the test twice because some compilers refuse to overwrite an
3859# existing .o file with -o, though they will create one.
3860ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
3861rm -f conftest2.*
3862if { (case "(($ac_try" in
3863 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
3864 *) ac_try_echo=$ac_try;;
3865esac
3866eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
3867$as_echo "$ac_try_echo") >&5
3868 (eval "$ac_try") 2>&5
3869 ac_status=$?
3870 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
3871 (exit $ac_status); } &&
3872 test -f conftest2.$ac_objext && { (case "(($ac_try" in
3873 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
3874 *) ac_try_echo=$ac_try;;
3875esac
3876eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
3877$as_echo "$ac_try_echo") >&5
3878 (eval "$ac_try") 2>&5
3879 ac_status=$?
3880 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
3881 (exit $ac_status); };
3882then
3883 eval ac_cv_prog_cc_${ac_cc}_c_o=yes
3884 if test "x$CC" != xcc; then
3885 # Test first that cc exists at all.
3886 if { ac_try='cc -c conftest.$ac_ext >&5'
3887 { (case "(($ac_try" in
3888 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
3889 *) ac_try_echo=$ac_try;;
3890esac
3891eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
3892$as_echo "$ac_try_echo") >&5
3893 (eval "$ac_try") 2>&5
3894 ac_status=$?
3895 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
3896 (exit $ac_status); }; }; then
3897 ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
3898 rm -f conftest2.*
3899 if { (case "(($ac_try" in
3900 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
3901 *) ac_try_echo=$ac_try;;
3902esac
3903eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
3904$as_echo "$ac_try_echo") >&5
3905 (eval "$ac_try") 2>&5
3906 ac_status=$?
3907 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
3908 (exit $ac_status); } &&
3909 test -f conftest2.$ac_objext && { (case "(($ac_try" in
3910 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
3911 *) ac_try_echo=$ac_try;;
3912esac
3913eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
3914$as_echo "$ac_try_echo") >&5
3915 (eval "$ac_try") 2>&5
3916 ac_status=$?
3917 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
3918 (exit $ac_status); };
3919 then
3920 # cc works too.
3921 :
3922 else
3923 # cc exists but doesn't like -o.
3924 eval ac_cv_prog_cc_${ac_cc}_c_o=no
3925 fi
3926 fi
3927 fi
3928else
3929 eval ac_cv_prog_cc_${ac_cc}_c_o=no
3930fi
3931rm -f core conftest*
3932
3933fi
3934if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
3935 { $as_echo "$as_me:$LINENO: result: yes" >&5
3936$as_echo "yes" >&6; }
3937else
3938 { $as_echo "$as_me:$LINENO: result: no" >&5
3939$as_echo "no" >&6; }
3940
3941cat >>confdefs.h <<\_ACEOF
3942#define NO_MINUS_C_MINUS_O 1
3943_ACEOF
3944
3945fi
3946
3947# FIXME: we rely on the cache variable name because
3948# there is no other way.
3949set dummy $CC
3950am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
3951eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
3952if test "$am_t" != yes; then
3953 # Losing compiler, so override with the script.
3954 # FIXME: It is wrong to rewrite CC.
3955 # But if we don't then we get into trouble of one sort or another.
3956 # A longer-term fix would be to have automake use am__CC in this case,
3957 # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
3958 CC="$am_aux_dir/compile $CC"
3959fi
3960
3961
38143962
3815 { $as_echo "$as_me:$LINENO: checking whether ${CC-cc} accepts -fPIE" >&53963 { $as_echo "$as_me:$LINENO: checking whether ${CC-cc} accepts -fPIE" >&5
3816$as_echo_n "checking whether ${CC-cc} accepts -fPIE... " >&6; }3964$as_echo_n "checking whether ${CC-cc} accepts -fPIE... " >&6; }
@@ -4731,13 +4879,13 @@
4731else4879else
4732 lt_cv_nm_interface="BSD nm"4880 lt_cv_nm_interface="BSD nm"
4733 echo "int some_variable = 0;" > conftest.$ac_ext4881 echo "int some_variable = 0;" > conftest.$ac_ext
4734 (eval echo "\"\$as_me:4734: $ac_compile\"" >&5)4882 (eval echo "\"\$as_me:4882: $ac_compile\"" >&5)
4735 (eval "$ac_compile" 2>conftest.err)4883 (eval "$ac_compile" 2>conftest.err)
4736 cat conftest.err >&54884 cat conftest.err >&5
4737 (eval echo "\"\$as_me:4737: $NM \\\"conftest.$ac_objext\\\"\"" >&5)4885 (eval echo "\"\$as_me:4885: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
4738 (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)4886 (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
4739 cat conftest.err >&54887 cat conftest.err >&5
4740 (eval echo "\"\$as_me:4740: output\"" >&5)4888 (eval echo "\"\$as_me:4888: output\"" >&5)
4741 cat conftest.out >&54889 cat conftest.out >&5
4742 if $GREP 'External.*some_variable' conftest.out > /dev/null; then4890 if $GREP 'External.*some_variable' conftest.out > /dev/null; then
4743 lt_cv_nm_interface="MS dumpbin"4891 lt_cv_nm_interface="MS dumpbin"
@@ -5943,7 +6091,7 @@
5943 ;;6091 ;;
5944*-*-irix6*)6092*-*-irix6*)
5945 # Find out which ABI we are using.6093 # Find out which ABI we are using.
5946 echo '#line 5946 "configure"' > conftest.$ac_ext6094 echo '#line 6094 "configure"' > conftest.$ac_ext
5947 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&56095 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
5948 (eval $ac_compile) 2>&56096 (eval $ac_compile) 2>&5
5949 ac_status=$?6097 ac_status=$?
@@ -7766,11 +7914,11 @@
7766 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \7914 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
7767 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \7915 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
7768 -e 's:$: $lt_compiler_flag:'`7916 -e 's:$: $lt_compiler_flag:'`
7769 (eval echo "\"\$as_me:7769: $lt_compile\"" >&5)7917 (eval echo "\"\$as_me:7917: $lt_compile\"" >&5)
7770 (eval "$lt_compile" 2>conftest.err)7918 (eval "$lt_compile" 2>conftest.err)
7771 ac_status=$?7919 ac_status=$?
7772 cat conftest.err >&57920 cat conftest.err >&5
7773 echo "$as_me:7773: \$? = $ac_status" >&57921 echo "$as_me:7921: \$? = $ac_status" >&5
7774 if (exit $ac_status) && test -s "$ac_outfile"; then7922 if (exit $ac_status) && test -s "$ac_outfile"; then
7775 # The compiler can only warn and ignore the option if not recognized7923 # The compiler can only warn and ignore the option if not recognized
7776 # So say no if there are warnings other than the usual output.7924 # So say no if there are warnings other than the usual output.
@@ -8105,11 +8253,11 @@
8105 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \8253 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
8106 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \8254 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
8107 -e 's:$: $lt_compiler_flag:'`8255 -e 's:$: $lt_compiler_flag:'`
8108 (eval echo "\"\$as_me:8108: $lt_compile\"" >&5)8256 (eval echo "\"\$as_me:8256: $lt_compile\"" >&5)
8109 (eval "$lt_compile" 2>conftest.err)8257 (eval "$lt_compile" 2>conftest.err)
8110 ac_status=$?8258 ac_status=$?
8111 cat conftest.err >&58259 cat conftest.err >&5
8112 echo "$as_me:8112: \$? = $ac_status" >&58260 echo "$as_me:8260: \$? = $ac_status" >&5
8113 if (exit $ac_status) && test -s "$ac_outfile"; then8261 if (exit $ac_status) && test -s "$ac_outfile"; then
8114 # The compiler can only warn and ignore the option if not recognized8262 # The compiler can only warn and ignore the option if not recognized
8115 # So say no if there are warnings other than the usual output.8263 # So say no if there are warnings other than the usual output.
@@ -8210,11 +8358,11 @@
8210 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \8358 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
8211 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \8359 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
8212 -e 's:$: $lt_compiler_flag:'`8360 -e 's:$: $lt_compiler_flag:'`
8213 (eval echo "\"\$as_me:8213: $lt_compile\"" >&5)8361 (eval echo "\"\$as_me:8361: $lt_compile\"" >&5)
8214 (eval "$lt_compile" 2>out/conftest.err)8362 (eval "$lt_compile" 2>out/conftest.err)
8215 ac_status=$?8363 ac_status=$?
8216 cat out/conftest.err >&58364 cat out/conftest.err >&5
8217 echo "$as_me:8217: \$? = $ac_status" >&58365 echo "$as_me:8365: \$? = $ac_status" >&5
8218 if (exit $ac_status) && test -s out/conftest2.$ac_objext8366 if (exit $ac_status) && test -s out/conftest2.$ac_objext
8219 then8367 then
8220 # The compiler can only warn and ignore the option if not recognized8368 # The compiler can only warn and ignore the option if not recognized
@@ -8265,11 +8413,11 @@
8265 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \8413 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
8266 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \8414 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
8267 -e 's:$: $lt_compiler_flag:'`8415 -e 's:$: $lt_compiler_flag:'`
8268 (eval echo "\"\$as_me:8268: $lt_compile\"" >&5)8416 (eval echo "\"\$as_me:8416: $lt_compile\"" >&5)
8269 (eval "$lt_compile" 2>out/conftest.err)8417 (eval "$lt_compile" 2>out/conftest.err)
8270 ac_status=$?8418 ac_status=$?
8271 cat out/conftest.err >&58419 cat out/conftest.err >&5
8272 echo "$as_me:8272: \$? = $ac_status" >&58420 echo "$as_me:8420: \$? = $ac_status" >&5
8273 if (exit $ac_status) && test -s out/conftest2.$ac_objext8421 if (exit $ac_status) && test -s out/conftest2.$ac_objext
8274 then8422 then
8275 # The compiler can only warn and ignore the option if not recognized8423 # The compiler can only warn and ignore the option if not recognized
@@ -11068,7 +11216,7 @@
11068 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=211216 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
11069 lt_status=$lt_dlunknown11217 lt_status=$lt_dlunknown
11070 cat > conftest.$ac_ext <<_LT_EOF11218 cat > conftest.$ac_ext <<_LT_EOF
11071#line 11071 "configure"11219#line 11219 "configure"
11072#include "confdefs.h"11220#include "confdefs.h"
1107311221
11074#if HAVE_DLFCN_H11222#if HAVE_DLFCN_H
@@ -11164,7 +11312,7 @@
11164 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=211312 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
11165 lt_status=$lt_dlunknown11313 lt_status=$lt_dlunknown
11166 cat > conftest.$ac_ext <<_LT_EOF11314 cat > conftest.$ac_ext <<_LT_EOF
11167#line 11167 "configure"11315#line 11315 "configure"
11168#include "confdefs.h"11316#include "confdefs.h"
1116911317
11170#if HAVE_DLFCN_H11318#if HAVE_DLFCN_H
@@ -12188,6 +12336,82 @@
12188fi12336fi
1218912337
1219012338
12339if (test "${phonebook_driver}" = "dummy"); then
12340
12341pkg_failed=no
12342{ $as_echo "$as_me:$LINENO: checking for LIBICAL" >&5
12343$as_echo_n "checking for LIBICAL... " >&6; }
12344
12345if test -n "$LIBICAL_CFLAGS"; then
12346 pkg_cv_LIBICAL_CFLAGS="$LIBICAL_CFLAGS"
12347 elif test -n "$PKG_CONFIG"; then
12348 if test -n "$PKG_CONFIG" && \
12349 { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libical\"") >&5
12350 ($PKG_CONFIG --exists --print-errors "libical") 2>&5
12351 ac_status=$?
12352 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
12353 (exit $ac_status); }; then
12354 pkg_cv_LIBICAL_CFLAGS=`$PKG_CONFIG --cflags "libical" 2>/dev/null`
12355else
12356 pkg_failed=yes
12357fi
12358 else
12359 pkg_failed=untried
12360fi
12361if test -n "$LIBICAL_LIBS"; then
12362 pkg_cv_LIBICAL_LIBS="$LIBICAL_LIBS"
12363 elif test -n "$PKG_CONFIG"; then
12364 if test -n "$PKG_CONFIG" && \
12365 { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libical\"") >&5
12366 ($PKG_CONFIG --exists --print-errors "libical") 2>&5
12367 ac_status=$?
12368 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
12369 (exit $ac_status); }; then
12370 pkg_cv_LIBICAL_LIBS=`$PKG_CONFIG --libs "libical" 2>/dev/null`
12371else
12372 pkg_failed=yes
12373fi
12374 else
12375 pkg_failed=untried
12376fi
12377
12378
12379
12380if test $pkg_failed = yes; then
12381
12382if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
12383 _pkg_short_errors_supported=yes
12384else
12385 _pkg_short_errors_supported=no
12386fi
12387 if test $_pkg_short_errors_supported = yes; then
12388 LIBICAL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libical" 2>&1`
12389 else
12390 LIBICAL_PKG_ERRORS=`$PKG_CONFIG --print-errors "libical" 2>&1`
12391 fi
12392 # Put the nasty error message in config.log where it belongs
12393 echo "$LIBICAL_PKG_ERRORS" >&5
12394
12395 { $as_echo "$as_me:$LINENO: result: no" >&5
12396$as_echo "no" >&6; }
12397 { { $as_echo "$as_me:$LINENO: error: libical is required" >&5
12398$as_echo "$as_me: error: libical is required" >&2;}
12399 { (exit 1); exit 1; }; }
12400elif test $pkg_failed = untried; then
12401 { { $as_echo "$as_me:$LINENO: error: libical is required" >&5
12402$as_echo "$as_me: error: libical is required" >&2;}
12403 { (exit 1); exit 1; }; }
12404else
12405 LIBICAL_CFLAGS=$pkg_cv_LIBICAL_CFLAGS
12406 LIBICAL_LIBS=$pkg_cv_LIBICAL_LIBS
12407 { $as_echo "$as_me:$LINENO: result: yes" >&5
12408$as_echo "yes" >&6; }
12409 dummy=yes
12410fi
12411
12412
12413fi
12414
12191if (test "${phonebook_driver}" = "ebook"); then12415if (test "${phonebook_driver}" = "ebook"); then
1219212416
12193cat >>confdefs.h <<\_ACEOF12417cat >>confdefs.h <<\_ACEOF
@@ -12363,6 +12587,40 @@
12363fi12587fi
1236412588
1236512589
12590# Check whether --enable-usb was given.
12591if test "${enable_usb+set}" = set; then
12592 enableval=$enable_usb;
12593 enable_usb=${enableval}
12594
12595fi
12596
12597 if test "${enable_usb}" = "yes" &&
12598 test "${enable_server}" != "no"; then
12599 USB_TRUE=
12600 USB_FALSE='#'
12601else
12602 USB_TRUE='#'
12603 USB_FALSE=
12604fi
12605
12606
12607# Check whether --enable-nokia_backup was given.
12608if test "${enable_nokia_backup+set}" = set; then
12609 enableval=$enable_nokia_backup;
12610 enable_nokia_backup=${enableval}
12611
12612fi
12613
12614 if test "${enable_nokia_backup}" = "yes" &&
12615 test "${enable_server}" != "no"; then
12616 NOKIA_BACKUP_TRUE=
12617 NOKIA_BACKUP_FALSE='#'
12618else
12619 NOKIA_BACKUP_TRUE='#'
12620 NOKIA_BACKUP_FALSE=
12621fi
12622
12623
12366# Check whether --enable-client was given.12624# Check whether --enable-client was given.
12367if test "${enable_client+set}" = set; then12625if test "${enable_client+set}" = set; then
12368 enableval=$enable_client;12626 enableval=$enable_client;
@@ -12514,6 +12772,20 @@
12514Usually this means the macro was only invoked conditionally." >&2;}12772Usually this means the macro was only invoked conditionally." >&2;}
12515 { (exit 1); exit 1; }; }12773 { (exit 1); exit 1; }; }
12516fi12774fi
12775if test -z "${USB_TRUE}" && test -z "${USB_FALSE}"; then
12776 { { $as_echo "$as_me:$LINENO: error: conditional \"USB\" was never defined.
12777Usually this means the macro was only invoked conditionally." >&5
12778$as_echo "$as_me: error: conditional \"USB\" was never defined.
12779Usually this means the macro was only invoked conditionally." >&2;}
12780 { (exit 1); exit 1; }; }
12781fi
12782if test -z "${NOKIA_BACKUP_TRUE}" && test -z "${NOKIA_BACKUP_FALSE}"; then
12783 { { $as_echo "$as_me:$LINENO: error: conditional \"NOKIA_BACKUP\" was never defined.
12784Usually this means the macro was only invoked conditionally." >&5
12785$as_echo "$as_me: error: conditional \"NOKIA_BACKUP\" was never defined.
12786Usually this means the macro was only invoked conditionally." >&2;}
12787 { (exit 1); exit 1; }; }
12788fi
12517if test -z "${CLIENT_TRUE}" && test -z "${CLIENT_FALSE}"; then12789if test -z "${CLIENT_TRUE}" && test -z "${CLIENT_FALSE}"; then
12518 { { $as_echo "$as_me:$LINENO: error: conditional \"CLIENT\" was never defined.12790 { { $as_echo "$as_me:$LINENO: error: conditional \"CLIENT\" was never defined.
12519Usually this means the macro was only invoked conditionally." >&512791Usually this means the macro was only invoked conditionally." >&5
@@ -12843,7 +13115,7 @@
12843# report actual input values of CONFIG_FILES etc. instead of their13115# report actual input values of CONFIG_FILES etc. instead of their
12844# values after options handling.13116# values after options handling.
12845ac_log="13117ac_log="
12846This file was extended by obexd $as_me 0.23, which was13118This file was extended by obexd $as_me 0.28, which was
12847generated by GNU Autoconf 2.63. Invocation command line was13119generated by GNU Autoconf 2.63. Invocation command line was
1284813120
12849 CONFIG_FILES = $CONFIG_FILES13121 CONFIG_FILES = $CONFIG_FILES
@@ -12906,7 +13178,7 @@
12906_ACEOF13178_ACEOF
12907cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=113179cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
12908ac_cs_version="\\13180ac_cs_version="\\
12909obexd config.status 0.2313181obexd config.status 0.28
12910configured by $0, generated by GNU Autoconf 2.63,13182configured by $0, generated by GNU Autoconf 2.63,
12911 with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"13183 with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
1291213184
1291313185
=== modified file 'configure.ac'
--- configure.ac 2010-04-27 04:17:15 +0000
+++ configure.ac 2010-06-15 19:18:33 +0000
@@ -1,5 +1,5 @@
1AC_PREREQ(2.60)1AC_PREREQ(2.60)
2AC_INIT(obexd, 0.23)2AC_INIT(obexd, 0.28)
33
4AM_INIT_AUTOMAKE([foreign subdir-objects])4AM_INIT_AUTOMAKE([foreign subdir-objects])
5AM_CONFIG_HEADER(config.h)5AM_CONFIG_HEADER(config.h)
@@ -30,6 +30,7 @@
30AC_LANG_C30AC_LANG_C
3131
32AC_PROG_CC32AC_PROG_CC
33AM_PROG_CC_C_O
33AC_PROG_CC_PIE34AC_PROG_CC_PIE
34AC_PROG_INSTALL35AC_PROG_INSTALL
35AC_PROG_SED36AC_PROG_SED
@@ -114,6 +115,13 @@
114 fi115 fi
115])116])
116117
118if (test "${phonebook_driver}" = "dummy"); then
119 PKG_CHECK_MODULES(LIBICAL, libical, dummy=yes,
120 AC_MSG_ERROR(libical is required))
121 AC_SUBST(LIBICAL_CFLAGS)
122 AC_SUBST(LIBICAL_LIBS)
123fi
124
117if (test "${phonebook_driver}" = "ebook"); then125if (test "${phonebook_driver}" = "ebook"); then
118 AC_DEFINE(NEED_THREADS, 1, [Define if threading support is required])126 AC_DEFINE(NEED_THREADS, 1, [Define if threading support is required])
119127
@@ -136,6 +144,20 @@
136])144])
137AM_CONDITIONAL(SERVER, test "${enable_server}" != "no")145AM_CONDITIONAL(SERVER, test "${enable_server}" != "no")
138146
147AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
148 [enable usb plugin]), [
149 enable_usb=${enableval}
150])
151AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
152 test "${enable_server}" != "no")
153
154AC_ARG_ENABLE(nokia_backup, AC_HELP_STRING([--enable-nokia-backup],
155 [enable nokia-backup plugin]), [
156 enable_nokia_backup=${enableval}
157])
158AM_CONDITIONAL(NOKIA_BACKUP, test "${enable_nokia_backup}" = "yes" &&
159 test "${enable_server}" != "no")
160
139AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],161AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],
140 [disable compilation of OBEX client]), [162 [disable compilation of OBEX client]), [
141 enable_client=${enableval}163 enable_client=${enableval}
142164
=== modified file 'debian/changelog'
--- debian/changelog 2010-04-27 04:17:15 +0000
+++ debian/changelog 2010-06-15 19:18:33 +0000
@@ -1,3 +1,43 @@
1obexd (0.28-0ubuntu1) UNRELEASED; urgency=low
2
3 * New upstream release.
4 - version 0.28:
5 + Fix broken assumption about contacts.
6 + Fix issue with exporting empty contacts.
7 + Fix issue with not always including the TEL header.
8 + Fix wrong response code for PBAP PUT operation.
9 + Fix handling of Tracker optional parameters.
10 + Fix queries for incoming and outgoing folders.
11 + Fix ordering during folder listing.
12 + Fix complex logic discovering the type of call.
13 + Add support for the X-IRMC-CALL-DATETIME field.
14 - version 0.27:
15 + Fix GET name handling with FTP service.
16 + Fix service driver matching when who is not specified.
17 + Fix object name not being updated when agent changes it.
18 + Fix inconsistency when using vCard version 2.1.
19 + Fix wrong response code to PUT requests for PBAP.
20 + Fix crash on PBAP SetPhoneBook function.
21 + Add support for transport drivers.
22 + Add support for Nokia backup plugin.
23 - version 0.26:
24 + Fix the order of the calls handles.
25 + Fix crash when receiving small objects.
26 + Fix invalid memory access when removing a file.
27 + Fix inverting the list with wrong search attribute.
28 + Fix wrong response code for dummy PullvCardListing.
29 + Fix sending the Not Found response asynchronously.
30 + Fix not resetting buffered data count when resetting the session.
31 + Add support for multiple telephone numbers.
32 + Add support for the ADR filter.
33 - version 0.25:
34 + Fix issue with missing phonebook-tracker.c file.
35 * debian/rules:
36 - enable usb and enable-nokia-backup plugins
37 * New upstream release.
38
39 -- Baptiste Mille-Mathias <baptiste.millemathias@gmail.com> Tue, 15 Jun 2010 20:48:39 +0200
40
1obexd (0.23-1) unstable; urgency=low41obexd (0.23-1) unstable; urgency=low
242
3 * New upstream release (Closes: #558710).43 * New upstream release (Closes: #558710).
444
=== modified file 'debian/control'
--- debian/control 2010-04-27 04:17:15 +0000
+++ debian/control 2010-06-15 19:18:33 +0000
@@ -7,7 +7,8 @@
7 libglib2.0-dev,7 libglib2.0-dev,
8 libdbus-1-dev,8 libdbus-1-dev,
9 libopenobex1-dev,9 libopenobex1-dev,
10 libbluetooth-dev (>= 4)10 libbluetooth-dev (>= 4),
11 libical-dev
11Vcs-Svn: svn://svn.debian.org/svn/pkg-bluetooth/packages/obexd12Vcs-Svn: svn://svn.debian.org/svn/pkg-bluetooth/packages/obexd
12Vcs-Browser: http://svn.debian.org/wsvn/pkg-bluetooth/packages/obexd13Vcs-Browser: http://svn.debian.org/wsvn/pkg-bluetooth/packages/obexd
13Homepage: http://www.bluez.org14Homepage: http://www.bluez.org
1415
=== modified file 'debian/rules'
--- debian/rules 2009-07-27 19:02:30 +0000
+++ debian/rules 2010-06-15 19:18:33 +0000
@@ -3,3 +3,7 @@
3include /usr/share/cdbs/1/rules/debhelper.mk3include /usr/share/cdbs/1/rules/debhelper.mk
4include /usr/share/cdbs/1/rules/simple-patchsys.mk4include /usr/share/cdbs/1/rules/simple-patchsys.mk
5include /usr/share/cdbs/1/class/autotools.mk5include /usr/share/cdbs/1/class/autotools.mk
6
7DEB_CONFIGURE_EXTRA_FLAGS += \
8 --enable-usb \
9 --enable-nokia-backup
610
=== modified file 'gdbus/object.c'
--- gdbus/object.c 2010-03-15 20:43:06 +0000
+++ gdbus/object.c 2010-06-15 19:18:33 +0000
@@ -308,8 +308,10 @@
308 goto done;308 goto done;
309309
310 if (!dbus_connection_get_object_path_data(conn, parent_path,310 if (!dbus_connection_get_object_path_data(conn, parent_path,
311 (void *) &data))311 (void *) &data)) {
312 invalidate_parent_data(conn, parent_path);
312 goto done;313 goto done;
314 }
313315
314 if (!data)316 if (!data)
315 goto done;317 goto done;
@@ -514,8 +516,10 @@
514 if (data == NULL)516 if (data == NULL)
515 return FALSE;517 return FALSE;
516518
517 if (find_interface(data->interfaces, name))519 if (find_interface(data->interfaces, name)) {
520 object_path_unref(connection, path);
518 return FALSE;521 return FALSE;
522 }
519523
520 add_interface(data, name, methods, signals,524 add_interface(data, name, methods, signals,
521 properties, user_data, destroy);525 properties, user_data, destroy);
522526
=== added file 'plugins/bluetooth.c'
--- plugins/bluetooth.c 1970-01-01 00:00:00 +0000
+++ plugins/bluetooth.c 2010-06-15 19:18:33 +0000
@@ -0,0 +1,609 @@
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
32#include <openobex/obex.h>
33#include <openobex/obex_const.h>
34
35#include <glib.h>
36#include <gdbus.h>
37
38#include "plugin.h"
39#include "server.h"
40#include "obex.h"
41#include "transport.h"
42#include "service.h"
43#include "logging.h"
44#include "btio.h"
45
46#define BT_RX_MTU 32767
47#define BT_TX_MTU 32767
48
49#define TIMEOUT 60*1000 /* Timeout for user response (miliseconds) */
50
51struct pending_request {
52 DBusPendingCall *call;
53 struct bluetooth_service *service;
54 char *adapter_path;
55 char address[18];
56 unsigned int watch;
57 GIOChannel *io;
58};
59
60struct bluetooth_service {
61 struct obex_server *server;
62 struct obex_service_driver *driver;
63 uint32_t handle;
64};
65
66struct adapter_any {
67 char *path; /* Adapter ANY path */
68 GSList *services; /* List of services to register records */
69};
70
71static DBusConnection *connection = NULL;
72static struct adapter_any *any = NULL;
73
74static void add_record_reply(DBusPendingCall *call, void *user_data)
75{
76 struct bluetooth_service *service = user_data;
77 DBusMessage *reply = dbus_pending_call_steal_reply(call);
78 DBusError derr;
79 uint32_t handle;
80
81 dbus_error_init(&derr);
82 if (dbus_set_error_from_message(&derr, reply)) {
83 error("bluetooth: Replied with an error: %s, %s",
84 derr.name, derr.message);
85 dbus_error_free(&derr);
86 handle = 0;
87 } else {
88 dbus_message_get_args(reply, NULL,
89 DBUS_TYPE_UINT32, &handle,
90 DBUS_TYPE_INVALID);
91
92 service->handle = handle;
93
94 debug("bluetooth: Registered: %s, handle: 0x%x",
95 service->driver->name, service->handle);
96 }
97
98 dbus_message_unref(reply);
99}
100
101static int add_record(const char *path, const char *xml,
102 struct bluetooth_service *service)
103{
104 DBusMessage *msg;
105 DBusPendingCall *call;
106 int ret = 0;
107
108 msg = dbus_message_new_method_call("org.bluez", path,
109 "org.bluez.Service", "AddRecord");
110
111 dbus_message_append_args(msg, DBUS_TYPE_STRING, &xml,
112 DBUS_TYPE_INVALID);
113
114 if (dbus_connection_send_with_reply(connection,
115 msg, &call, -1) == FALSE) {
116 ret = -1;
117 goto failed;
118 }
119
120 dbus_pending_call_set_notify(call, add_record_reply, service, NULL);
121 dbus_pending_call_unref(call);
122
123failed:
124 dbus_message_unref(msg);
125 return ret;
126}
127
128static struct bluetooth_service *find_service(
129 struct obex_service_driver *driver,
130 uint8_t channel)
131{
132 GSList *l;
133
134 for (l = any->services; l; l = l->next) {
135 struct bluetooth_service *service = l->data;
136
137 if (driver != NULL && service->driver != driver)
138 continue;
139
140 if (channel != 0 && service->driver->channel != channel)
141 continue;
142
143 return service;
144 }
145
146 return NULL;
147}
148
149static void register_record(struct obex_server *server)
150{
151 const GSList *l;
152
153 if (connection == NULL)
154 return;
155
156 for (l = server->drivers; l; l = l->next) {
157 struct obex_service_driver *driver = l->data;
158 struct bluetooth_service *service;
159 char *xml;
160
161 service = find_service(driver, 0);
162 if (service == NULL) {
163 service = g_new0(struct bluetooth_service, 1);
164 service->driver = driver;
165 service->server = server;
166 any->services = g_slist_append(any->services, service);
167 }
168
169 /* Service already has a record registered */
170 if (service->handle != 0)
171 continue;
172
173 /* Adapter ANY is not available yet: Add record later */
174 if (any->path == NULL)
175 continue;
176
177 xml = g_markup_printf_escaped(driver->record, driver->channel,
178 driver->name);
179 add_record(any->path, xml, service);
180 g_free(xml);
181 }
182}
183
184static void find_adapter_any_reply(DBusPendingCall *call, void *user_data)
185{
186 DBusMessage *reply = dbus_pending_call_steal_reply(call);
187 const char *path;
188 GSList *l;
189 DBusError derr;
190
191 dbus_error_init(&derr);
192 if (dbus_set_error_from_message(&derr, reply)) {
193 error("bluetooth: Replied with an error: %s, %s",
194 derr.name, derr.message);
195 dbus_error_free(&derr);
196 goto done;
197 }
198
199 dbus_message_get_args(reply, NULL,
200 DBUS_TYPE_OBJECT_PATH, &path,
201 DBUS_TYPE_INVALID);
202 any->path = g_strdup(path);
203
204 for (l = any->services; l; l = l->next) {
205 struct bluetooth_service *service = l->data;
206 char *xml;
207
208 xml = g_markup_printf_escaped(service->driver->record,
209 service->driver->channel,
210 service->driver->name);
211 add_record(any->path, xml, service);
212 g_free(xml);
213 }
214
215done:
216 dbus_message_unref(reply);
217}
218
219static DBusPendingCall *find_adapter(const char *pattern,
220 DBusPendingCallNotifyFunction function,
221 void *user_data)
222{
223 DBusMessage *msg;
224 DBusPendingCall *call;
225
226 debug("bluetooth: FindAdapter(%s)", pattern);
227
228 msg = dbus_message_new_method_call("org.bluez", "/",
229 "org.bluez.Manager", "FindAdapter");
230 if (!msg)
231 return NULL;
232
233 dbus_message_append_args(msg, DBUS_TYPE_STRING, &pattern,
234 DBUS_TYPE_INVALID);
235
236 if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
237 dbus_message_unref(msg);
238 return NULL;
239 }
240
241 dbus_pending_call_set_notify(call, function, user_data, NULL);
242
243 dbus_message_unref(msg);
244
245 return call;
246}
247
248static void name_acquired(DBusConnection *conn, void *user_data)
249{
250 DBusPendingCall *call;
251
252 call = find_adapter("any", find_adapter_any_reply, NULL);
253 if (call)
254 dbus_pending_call_unref(call);
255}
256
257static void name_released(DBusConnection *conn, void *user_data)
258{
259 GSList *l;
260
261 /* reset handles so the services got register next time */
262 for (l = any->services; l; l = l->next) {
263 struct bluetooth_service *service = l->data;
264
265 service->handle = 0;
266 }
267
268 g_free(any->path);
269 any->path = NULL;
270
271}
272
273static void service_cancel(struct pending_request *pending)
274{
275 DBusMessage *msg;
276
277 msg = dbus_message_new_method_call("org.bluez",
278 pending->adapter_path,
279 "org.bluez.Service",
280 "CancelAuthorization");
281
282 g_dbus_send_message(connection, msg);
283}
284
285static void pending_request_free(struct pending_request *pending)
286{
287 if (pending->call)
288 dbus_pending_call_unref(pending->call);
289 g_io_channel_unref(pending->io);
290 g_free(pending->adapter_path);
291 g_free(pending);
292}
293
294static void connect_event(GIOChannel *io, GError *err, void *user_data)
295{
296 struct bluetooth_service *service = user_data;
297 struct obex_server *server = service->server;
298
299 if (err)
300 goto drop;
301
302 if (obex_server_new_connection(server, io, BT_TX_MTU, BT_RX_MTU) < 0)
303 g_io_channel_shutdown(io, TRUE, NULL);
304
305 return;
306
307drop:
308 error("%s", err->message);
309 g_io_channel_shutdown(io, TRUE, NULL);
310 return;
311}
312
313static void service_reply(DBusPendingCall *call, void *user_data)
314{
315 struct pending_request *pending = user_data;
316 GIOChannel *io = pending->io;
317 struct bluetooth_service *service = pending->service;
318 DBusMessage *reply = dbus_pending_call_steal_reply(call);
319 DBusError derr;
320 GError *err = NULL;
321
322 dbus_error_init(&derr);
323 if (dbus_set_error_from_message(&derr, reply)) {
324 error("bluetooth: RequestAuthorization error: %s, %s",
325 derr.name, derr.message);
326
327 if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY))
328 service_cancel(pending);
329
330 dbus_error_free(&derr);
331 g_io_channel_shutdown(io, TRUE, NULL);
332 goto done;
333 }
334
335 debug("bluetooth: RequestAuthorization succeeded");
336
337 if (!bt_io_accept(io, connect_event, service, NULL, &err)) {
338 error("%s", err->message);
339 g_error_free(err);
340 g_io_channel_shutdown(io, TRUE, NULL);
341 }
342
343done:
344 g_source_remove(pending->watch);
345 pending_request_free(pending);
346 dbus_message_unref(reply);
347}
348
349static gboolean service_error(GIOChannel *io, GIOCondition cond,
350 void *user_data)
351{
352 struct pending_request *pending = user_data;
353
354 service_cancel(pending);
355
356 dbus_pending_call_cancel(pending->call);
357
358 pending_request_free(pending);
359
360 return FALSE;
361}
362
363static void find_adapter_reply(DBusPendingCall *call, void *user_data)
364{
365 struct pending_request *pending = user_data;
366 DBusMessage *reply = dbus_pending_call_steal_reply(call);
367 DBusMessage *msg;
368 DBusPendingCall *pcall;
369 const char *path, *paddr = pending->address;
370 DBusError derr;
371
372 dbus_error_init(&derr);
373 if (dbus_set_error_from_message(&derr, reply)) {
374 error("Replied with an error: %s, %s",
375 derr.name, derr.message);
376 dbus_error_free(&derr);
377 goto failed;
378 }
379
380 dbus_message_get_args(reply, NULL,
381 DBUS_TYPE_OBJECT_PATH, &path,
382 DBUS_TYPE_INVALID);
383
384 debug("bluetooth: FindAdapter -> %s", path);
385 pending->adapter_path = g_strdup(path);
386 dbus_message_unref(reply);
387
388 msg = dbus_message_new_method_call("org.bluez", path,
389 "org.bluez.Service", "RequestAuthorization");
390
391 dbus_message_append_args(msg, DBUS_TYPE_STRING, &paddr,
392 DBUS_TYPE_UINT32, &pending->service->handle,
393 DBUS_TYPE_INVALID);
394
395 if (!dbus_connection_send_with_reply(connection,
396 msg, &pcall, TIMEOUT)) {
397 dbus_message_unref(msg);
398 goto failed;
399 }
400
401 dbus_message_unref(msg);
402
403 debug("bluetooth: RequestAuthorization(%s, %x)", paddr,
404 pending->service->handle);
405
406 if (!dbus_pending_call_set_notify(pcall, service_reply, pending,
407 NULL)) {
408 dbus_pending_call_unref(pcall);
409 goto failed;
410 }
411
412 dbus_pending_call_unref(pending->call);
413 pending->call = pcall;
414
415 /* Catches errors before authorization response comes */
416 pending->watch = g_io_add_watch(pending->io,
417 G_IO_HUP | G_IO_ERR | G_IO_NVAL,
418 service_error, pending);
419
420 return;
421
422failed:
423 g_io_channel_shutdown(pending->io, TRUE, NULL);
424 pending_request_free(pending);
425}
426
427static int request_service_authorization(struct bluetooth_service *service,
428 GIOChannel *io, const char *address)
429{
430 struct pending_request *pending;
431 char source[18];
432 GError *err = NULL;
433
434 if (connection == NULL || any->path == NULL)
435 return -1;
436
437 bt_io_get(io, BT_IO_RFCOMM, &err,
438 BT_IO_OPT_SOURCE, source,
439 BT_IO_OPT_INVALID);
440 if (err) {
441 error("%s", err->message);
442 g_error_free(err);
443 return -EINVAL;
444 }
445
446 pending = g_new0(struct pending_request, 1);
447 pending->call = find_adapter(source, find_adapter_reply, pending);
448 if (!pending->call) {
449 g_free(pending);
450 return -ENOMEM;
451 }
452
453 pending->service = service;
454 pending->io = g_io_channel_ref(io);
455 memcpy(pending->address, address, sizeof(pending->address));
456
457 return 0;
458}
459
460static void confirm_event(GIOChannel *io, void *user_data)
461{
462 struct bluetooth_service *service;
463 GError *err = NULL;
464 char address[18];
465 uint8_t channel;
466
467 bt_io_get(io, BT_IO_RFCOMM, &err,
468 BT_IO_OPT_DEST, address,
469 BT_IO_OPT_CHANNEL, &channel,
470 BT_IO_OPT_INVALID);
471 if (err) {
472 error("%s", err->message);
473 g_error_free(err);
474 goto drop;
475 }
476
477 info("bluetooth: New connection from: %s, channel %u", address,
478 channel);
479
480 service = find_service(NULL, channel);
481 if (service == NULL) {
482 error("bluetooth: Unable to find service");
483 goto drop;
484 }
485
486 if (service->driver->service != OBEX_OPP) {
487 if (request_service_authorization(service, io, address) < 0)
488 goto drop;
489
490 return;
491 }
492
493 if (!bt_io_accept(io, connect_event, service, NULL, &err)) {
494 error("%s", err->message);
495 g_error_free(err);
496 goto drop;
497 }
498
499 return;
500
501drop:
502 g_io_channel_shutdown(io, TRUE, NULL);
503}
504
505static GIOChannel *start(struct obex_server *server,
506 struct obex_service_driver *service,
507 BtIOSecLevel sec_level)
508{
509 GIOChannel *io;
510 GError *err = NULL;
511
512 io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event,
513 server, NULL, &err,
514 BT_IO_OPT_CHANNEL, service->channel,
515 BT_IO_OPT_SEC_LEVEL, sec_level,
516 BT_IO_OPT_INVALID);
517 if (io == NULL) {
518 error("bluetooth: unable to listen in channel %d: %s",
519 service->channel, err->message);
520 g_error_free(err);
521 } else
522 debug("bluetooth: listening on channel %d", service->channel);
523
524 return io;
525}
526
527static void *bluetooth_start(struct obex_server *server, int *err)
528{
529 BtIOSecLevel sec_level;
530 GSList *ios = NULL;
531 const GSList *l;
532
533 if (server->secure == TRUE)
534 sec_level = BT_IO_SEC_MEDIUM;
535 else
536 sec_level = BT_IO_SEC_LOW;
537
538 for (l = server->drivers; l; l = l->next) {
539 struct obex_service_driver *service = l->data;
540 GIOChannel *io;
541
542 io = start(server, service, sec_level);
543 if (io == NULL)
544 continue;
545
546 ios = g_slist_prepend(ios, io);
547 }
548
549 register_record(server);
550
551 return ios;
552}
553
554static void stop(gpointer data, gpointer user_data)
555{
556 GIOChannel *io = data;
557
558 g_io_channel_shutdown(io, TRUE, NULL);
559 g_io_channel_unref(io);
560}
561
562static void bluetooth_stop(void *data)
563{
564 GSList *ios = data;
565
566 g_slist_foreach(ios, stop, NULL);
567 g_slist_free(ios);
568}
569
570static struct obex_transport_driver driver = {
571 .name = "bluetooth",
572 .start = bluetooth_start,
573 .stop = bluetooth_stop
574};
575
576static unsigned int listener_id = 0;
577
578static int bluetooth_init(void)
579{
580 any = g_new0(struct adapter_any, 1);
581
582 connection = g_dbus_setup_private(DBUS_BUS_SYSTEM, NULL, NULL);
583 if (connection == NULL)
584 return -EPERM;
585
586 listener_id = g_dbus_add_service_watch(connection, "org.bluez",
587 name_acquired, name_released, NULL, NULL);
588
589 return obex_transport_driver_register(&driver);
590}
591
592static void bluetooth_exit(void)
593{
594 g_dbus_remove_watch(connection, listener_id);
595
596 if (any) {
597 g_slist_foreach(any->services, (GFunc) g_free, NULL);
598 g_slist_free(any->services);
599 g_free(any->path);
600 g_free(any);
601 }
602
603 if (connection)
604 dbus_connection_unref(connection);
605
606 obex_transport_driver_unregister(&driver);
607}
608
609OBEX_PLUGIN_DEFINE(bluetooth, bluetooth_init, bluetooth_exit)
0610
=== modified file 'plugins/filesystem.c'
--- plugins/filesystem.c 2010-04-27 04:17:15 +0000
+++ plugins/filesystem.c 2010-06-15 19:18:33 +0000
@@ -58,7 +58,7 @@
58#define FL_TYPE "<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\">" EOL_CHARS58#define FL_TYPE "<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\">" EOL_CHARS
5959
60#define FL_TYPE_PCSUITE "<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\"" EOL_CHARS \60#define FL_TYPE_PCSUITE "<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\"" EOL_CHARS \
61 " [ <!ATTLIST folder mem-type CDATA #IMPLIED> ]>" EOL_CHARS61 " [ <!ATTLIST folder mem-type CDATA #IMPLIED> ]>" EOL_CHARS
6262
63#define FL_BODY_BEGIN "<folder-listing version=\"1.0\">" EOL_CHARS63#define FL_BODY_BEGIN "<folder-listing version=\"1.0\">" EOL_CHARS
6464
@@ -77,16 +77,22 @@
77 " modified=\"%s\" mem-type=\"DEV\"" \77 " modified=\"%s\" mem-type=\"DEV\"" \
78 " created=\"%s\"/>" EOL_CHARS78 " created=\"%s\"/>" EOL_CHARS
7979
80static const guint8 FTP_TARGET[TARGET_SIZE] = {80static const uint8_t FTP_TARGET[TARGET_SIZE] = {
81 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,81 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
82 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };82 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
8383
84static gchar *file_stat_line(gchar *filename, struct stat *fstat,84#define PCSUITE_WHO_SIZE 8
85 struct stat *dstat, gboolean root,85
86 gboolean pcsuite)86static const uint8_t PCSUITE_WHO[PCSUITE_WHO_SIZE] = {
87 'P','C',' ','S','u','i','t','e' };
88
89
90static char *file_stat_line(char *filename, struct stat *fstat,
91 struct stat *dstat, gboolean root,
92 gboolean pcsuite)
87{93{
88 gchar perm[51], atime[18], ctime[18], mtime[18];94 char perm[51], atime[18], ctime[18], mtime[18];
89 gchar *escaped, *ret = NULL;95 char *escaped, *ret = NULL;
9096
91 snprintf(perm, 50, "user-perm=\"%s%s%s\" group-perm=\"%s%s%s\" "97 snprintf(perm, 50, "user-perm=\"%s%s%s\" group-perm=\"%s%s%s\" "
92 "other-perm=\"%s%s%s\"",98 "other-perm=\"%s%s%s\"",
@@ -113,22 +119,26 @@
113 mtime, ctime);119 mtime, ctime);
114 else120 else
115 ret = g_strdup_printf(FL_FOLDER_ELEMENT, escaped, perm,121 ret = g_strdup_printf(FL_FOLDER_ELEMENT, escaped, perm,
116 atime, mtime, ctime);122 atime, mtime, ctime);
117 } else if (S_ISREG(fstat->st_mode))123 } else if (S_ISREG(fstat->st_mode))
118 ret = g_strdup_printf(FL_FILE_ELEMENT, escaped, fstat->st_size,124 ret = g_strdup_printf(FL_FILE_ELEMENT, escaped, fstat->st_size,
119 perm, atime, mtime, ctime);125 perm, atime, mtime, ctime);
120126
121 g_free(escaped);127 g_free(escaped);
122128
123 return ret;129 return ret;
124}130}
125131
126static gpointer filesystem_open(const char *name, int oflag, mode_t mode,132static void *filesystem_open(const char *name, int oflag, mode_t mode,
127 gpointer context, size_t *size, int *err)133 void *context, size_t *size, int *err)
128{134{
129 struct stat stats;135 struct stat stats;
130 struct statvfs buf;136 struct statvfs buf;
137 const char *root_folder;
138 char *folder;
139 gboolean root;
131 int fd = open(name, oflag, mode);140 int fd = open(name, oflag, mode);
141 uint64_t avail;
132142
133 if (fd < 0) {143 if (fd < 0) {
134 if (err)144 if (err)
@@ -142,6 +152,21 @@
142 goto failed;152 goto failed;
143 }153 }
144154
155 root_folder = obex_option_root_folder();
156 folder = g_path_get_dirname(name);
157 root = g_strcmp0(folder, root_folder);
158
159 g_free(folder);
160
161 if (!root || obex_option_symlinks()) {
162 if (S_ISLNK(stats.st_mode)) {
163 if (err)
164 *err = -EPERM;
165 goto failed;
166 }
167
168 }
169
145 if (oflag == O_RDONLY) {170 if (oflag == O_RDONLY) {
146 if (size)171 if (size)
147 *size = stats.st_size;172 *size = stats.st_size;
@@ -157,7 +182,8 @@
157 if (size == NULL)182 if (size == NULL)
158 goto done;183 goto done;
159184
160 if (buf.f_bsize * buf.f_bavail < *size) {185 avail = (uint64_t) buf.f_bsize * buf.f_bavail;
186 if (avail < *size) {
161 if (err)187 if (err)
162 *err = -ENOSPC;188 *err = -ENOSPC;
163 goto failed;189 goto failed;
@@ -174,7 +200,7 @@
174 return NULL;200 return NULL;
175}201}
176202
177static int filesystem_close(gpointer object)203static int filesystem_close(void *object)
178{204{
179 if (close(GPOINTER_TO_INT(object)) < 0)205 if (close(GPOINTER_TO_INT(object)) < 0)
180 return -errno;206 return -errno;
@@ -182,7 +208,8 @@
182 return 0;208 return 0;
183}209}
184210
185static ssize_t filesystem_read(gpointer object, void *buf, size_t count)211static ssize_t filesystem_read(void *object, void *buf, size_t count,
212 uint8_t *hi)
186{213{
187 ssize_t ret;214 ssize_t ret;
188215
@@ -190,10 +217,12 @@
190 if (ret < 0)217 if (ret < 0)
191 return -errno;218 return -errno;
192219
220 *hi = OBEX_HDR_BODY;
221
193 return ret;222 return ret;
194}223}
195224
196static ssize_t filesystem_write(gpointer object, const void *buf, size_t count)225static ssize_t filesystem_write(void *object, const void *buf, size_t count)
197{226{
198 ssize_t ret;227 ssize_t ret;
199228
@@ -208,11 +237,11 @@
208 int pid;237 int pid;
209 int output;238 int output;
210 int err;239 int err;
211 guint watch;240 unsigned int watch;
212 GString *buffer;241 GString *buffer;
213};242};
214243
215static void script_exited(GPid pid, gint status, gpointer data)244static void script_exited(GPid pid, int status, void *data)
216{245{
217 struct capability_object *object = data;246 struct capability_object *object = data;
218 char buf[128];247 char buf[128];
@@ -246,11 +275,11 @@
246 return pid;275 return pid;
247}276}
248277
249static gpointer capability_open(const char *name, int oflag, mode_t mode,278static void *capability_open(const char *name, int oflag, mode_t mode,
250 gpointer context, size_t *size, int *err)279 void *context, size_t *size, int *err)
251{280{
252 struct capability_object *object = NULL;281 struct capability_object *object = NULL;
253 gchar *buf;282 char *buf;
254 const char *argv[2];283 const char *argv[2];
255284
256 if (oflag != O_RDONLY)285 if (oflag != O_RDONLY)
@@ -306,25 +335,26 @@
306 return NULL;335 return NULL;
307}336}
308337
309static gpointer folder_open(const char *name, int oflag, mode_t mode,338static GString *append_pcsuite_preamble(GString *object)
310 gpointer context, size_t *size, int *err)339{
311{340 return g_string_append(object, FL_TYPE_PCSUITE);
312 struct obex_session *os = context;341}
342
343static GString *append_folder_preamble(GString *object)
344{
345 return g_string_append(object, FL_TYPE);
346}
347
348static GString *append_listing(GString *object, const char *name,
349 gboolean pcsuite, size_t *size, int *err)
350{
313 struct stat fstat, dstat;351 struct stat fstat, dstat;
314 struct dirent *ep;352 struct dirent *ep;
315 GString *object;
316 DIR *dp;353 DIR *dp;
317 gboolean root, pcsuite, symlinks;354 gboolean root, symlinks;
318 gint ret;355 int ret;
319356
320 pcsuite = obex_get_service(os) & OBEX_PCSUITE ? TRUE : FALSE;357 root = g_str_equal(name, obex_option_root_folder());
321
322 object = g_string_new(FL_VERSION);
323 object = g_string_append(object, pcsuite ? FL_TYPE_PCSUITE : FL_TYPE);
324
325 object = g_string_append(object, FL_BODY_BEGIN);
326
327 root = g_str_equal(name, obex_get_root_folder(os));
328358
329 dp = opendir(name);359 dp = opendir(name);
330 if (dp == NULL) {360 if (dp == NULL) {
@@ -333,7 +363,7 @@
333 goto failed;363 goto failed;
334 }364 }
335365
336 symlinks = obex_get_symlinks(os);366 symlinks = obex_option_symlinks();
337 if (root && symlinks)367 if (root && symlinks)
338 ret = stat(name, &dstat);368 ret = stat(name, &dstat);
339 else {369 else {
@@ -348,9 +378,9 @@
348 }378 }
349379
350 while ((ep = readdir(dp))) {380 while ((ep = readdir(dp))) {
351 gchar *filename;381 char *filename;
352 gchar *fullname;382 char *fullname;
353 gchar *line;383 char *line;
354384
355 if (ep->d_name[0] == '.')385 if (ep->d_name[0] == '.')
356 continue;386 continue;
@@ -378,7 +408,7 @@
378408
379 g_free(fullname);409 g_free(fullname);
380410
381 line = file_stat_line(filename, &fstat, &dstat, root, pcsuite);411 line = file_stat_line(filename, &fstat, &dstat, root, FALSE);
382 if (line == NULL) {412 if (line == NULL) {
383 g_free(filename);413 g_free(filename);
384 continue;414 continue;
@@ -409,7 +439,31 @@
409 return NULL;439 return NULL;
410}440}
411441
412int string_free(gpointer object)442static void *folder_open(const char *name, int oflag, mode_t mode,
443 void *context, size_t *size, int *err)
444{
445 GString *object;
446
447 object = g_string_new(FL_VERSION);
448 object = append_folder_preamble(object);
449 object = g_string_append(object, FL_BODY_BEGIN);
450
451 return append_listing(object, name, FALSE, size, err);
452}
453
454static void *pcsuite_open(const char *name, int oflag, mode_t mode,
455 void *context, size_t *size, int *err)
456{
457 GString *object;
458
459 object = g_string_new(FL_VERSION);
460 object = append_pcsuite_preamble(object);
461 object = g_string_append(object, FL_BODY_BEGIN);
462
463 return append_listing(object, name, TRUE, size, err);
464}
465
466int string_free(void *object)
413{467{
414 GString *string = object;468 GString *string = object;
415469
@@ -418,7 +472,7 @@
418 return 0;472 return 0;
419}473}
420474
421ssize_t string_read(gpointer object, void *buf, size_t count)475ssize_t string_read(void *object, void *buf, size_t count)
422{476{
423 GString *string = object;477 GString *string = object;
424 ssize_t len;478 ssize_t len;
@@ -433,10 +487,19 @@
433 return len;487 return len;
434}488}
435489
436static ssize_t capability_read(gpointer object, void *buf, size_t count)490static ssize_t folder_read(void *object, void *buf, size_t count, uint8_t *hi)
491{
492 *hi = OBEX_HDR_BODY;
493 return string_read(object, buf, count);
494}
495
496static ssize_t capability_read(void *object, void *buf, size_t count,
497 uint8_t *hi)
437{498{
438 struct capability_object *obj = object;499 struct capability_object *obj = object;
439500
501 *hi = OBEX_HDR_BODY;
502
440 if (obj->buffer)503 if (obj->buffer)
441 return string_read(obj->buffer, buf, count);504 return string_read(obj->buffer, buf, count);
442505
@@ -446,7 +509,7 @@
446 return read(obj->output, buf, count);509 return read(obj->output, buf, count);
447}510}
448511
449static int capability_close(gpointer object)512static int capability_close(void *object)
450{513{
451 struct capability_object *obj = object;514 struct capability_object *obj = object;
452515
@@ -464,7 +527,7 @@
464 return 0;527 return 0;
465}528}
466529
467struct obex_mime_type_driver file = {530static struct obex_mime_type_driver file = {
468 .open = filesystem_open,531 .open = filesystem_open,
469 .close = filesystem_close,532 .close = filesystem_close,
470 .read = filesystem_read,533 .read = filesystem_read,
@@ -472,7 +535,7 @@
472 .remove = remove,535 .remove = remove,
473};536};
474537
475struct obex_mime_type_driver capability = {538static struct obex_mime_type_driver capability = {
476 .target = FTP_TARGET,539 .target = FTP_TARGET,
477 .mimetype = "x-obex/capability",540 .mimetype = "x-obex/capability",
478 .open = capability_open,541 .open = capability_open,
@@ -480,12 +543,22 @@
480 .read = capability_read,543 .read = capability_read,
481};544};
482545
483struct obex_mime_type_driver folder = {546static struct obex_mime_type_driver folder = {
484 .target = FTP_TARGET,547 .target = FTP_TARGET,
485 .mimetype = "x-obex/folder-listing",548 .mimetype = "x-obex/folder-listing",
486 .open = folder_open,549 .open = folder_open,
487 .close = string_free,550 .close = string_free,
488 .read = string_read,551 .read = folder_read,
552};
553
554static struct obex_mime_type_driver pcsuite = {
555 .target = FTP_TARGET,
556 .who = PCSUITE_WHO,
557 .who_size = PCSUITE_WHO_SIZE,
558 .mimetype = "x-obex/folder-listing",
559 .open = pcsuite_open,
560 .close = string_free,
561 .read = folder_read,
489};562};
490563
491static int filesystem_init(void)564static int filesystem_init(void)
@@ -500,6 +573,10 @@
500 if (err < 0)573 if (err < 0)
501 return err;574 return err;
502575
576 err = obex_mime_type_driver_register(&pcsuite);
577 if (err < 0)
578 return err;
579
503 return obex_mime_type_driver_register(&file);580 return obex_mime_type_driver_register(&file);
504}581}
505582
506583
=== modified file 'plugins/filesystem.h'
--- plugins/filesystem.h 2010-04-27 04:17:15 +0000
+++ plugins/filesystem.h 2010-06-15 19:18:33 +0000
@@ -21,5 +21,5 @@
21 *21 *
22 */22 */
2323
24int string_free(gpointer object);24int string_free(void *object);
25ssize_t string_read(gpointer object, void *buf, size_t count);25ssize_t string_read(void *object, void *buf, size_t count);
2626
=== modified file 'plugins/ftp.c'
--- plugins/ftp.c 2010-04-27 04:17:15 +0000
+++ plugins/ftp.c 2010-06-15 19:18:33 +0000
@@ -54,99 +54,100 @@
54#define LST_TYPE "x-obex/folder-listing"54#define LST_TYPE "x-obex/folder-listing"
55#define CAP_TYPE "x-obex/capability"55#define CAP_TYPE "x-obex/capability"
5656
57#define FTP_CHANNEL 1057#define FTP_CHANNEL 10
58#define FTP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \58#define FTP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
59<record> \59<record> \
60 <attribute id=\"0x0001\"> \60 <attribute id=\"0x0001\"> \
61 <sequence> \61 <sequence> \
62 <uuid value=\"0x1106\"/> \62 <uuid value=\"0x1106\"/> \
63 </sequence> \63 </sequence> \
64 </attribute> \64 </attribute> \
65 \65 \
66 <attribute id=\"0x0004\"> \66 <attribute id=\"0x0004\"> \
67 <sequence> \67 <sequence> \
68 <sequence> \68 <sequence> \
69 <uuid value=\"0x0100\"/> \69 <uuid value=\"0x0100\"/> \
70 </sequence> \70 </sequence> \
71 <sequence> \71 <sequence> \
72 <uuid value=\"0x0003\"/> \72 <uuid value=\"0x0003\"/> \
73 <uint8 value=\"%u\" name=\"channel\"/> \73 <uint8 value=\"%u\" name=\"channel\"/> \
74 </sequence> \74 </sequence> \
75 <sequence> \75 <sequence> \
76 <uuid value=\"0x0008\"/> \76 <uuid value=\"0x0008\"/> \
77 </sequence> \77 </sequence> \
78 </sequence> \78 </sequence> \
79 </attribute> \79 </attribute> \
80 \80 \
81 <attribute id=\"0x0009\"> \81 <attribute id=\"0x0009\"> \
82 <sequence> \82 <sequence> \
83 <sequence> \83 <sequence> \
84 <uuid value=\"0x1106\"/> \84 <uuid value=\"0x1106\"/> \
85 <uint16 value=\"0x0100\" name=\"version\"/> \85 <uint16 value=\"0x0100\" name=\"version\"/> \
86 </sequence> \86 </sequence> \
87 </sequence> \87 </sequence> \
88 </attribute> \88 </attribute> \
89 \89 \
90 <attribute id=\"0x0100\"> \90 <attribute id=\"0x0100\"> \
91 <text value=\"%s\" name=\"name\"/> \91 <text value=\"%s\" name=\"name\"/> \
92 </attribute> \92 </attribute> \
93</record>"93</record>"
9494
95#define PCSUITE_CHANNEL 2495#define PCSUITE_CHANNEL 24
96#define PCSUITE_WHO_SIZE 896#define PCSUITE_WHO_SIZE 8
97#define PCSUITE_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \97
98<record> \98#define PCSUITE_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
99 <attribute id=\"0x0001\"> \99<record> \
100 <sequence> \100 <attribute id=\"0x0001\"> \
101 <uuid value=\"00005005-0000-1000-8000-0002ee000001\"/> \101 <sequence> \
102 </sequence> \102 <uuid value=\"00005005-0000-1000-8000-0002ee000001\"/> \
103 </attribute> \103 </sequence> \
104 \104 </attribute> \
105 <attribute id=\"0x0004\"> \105 \
106 <sequence> \106 <attribute id=\"0x0004\"> \
107 <sequence> \107 <sequence> \
108 <uuid value=\"0x0100\"/> \108 <sequence> \
109 </sequence> \109 <uuid value=\"0x0100\"/> \
110 <sequence> \110 </sequence> \
111 <uuid value=\"0x0003\"/> \111 <sequence> \
112 <uint8 value=\"%u\" name=\"channel\"/> \112 <uuid value=\"0x0003\"/> \
113 </sequence> \113 <uint8 value=\"%u\" name=\"channel\"/> \
114 <sequence> \114 </sequence> \
115 <uuid value=\"0x0008\"/> \115 <sequence> \
116 </sequence> \116 <uuid value=\"0x0008\"/> \
117 </sequence> \117 </sequence> \
118 </attribute> \118 </sequence> \
119 \119 </attribute> \
120 <attribute id=\"0x0005\"> \120 \
121 <sequence> \121 <attribute id=\"0x0005\"> \
122 <uuid value=\"0x1002\"/> \122 <sequence> \
123 </sequence> \123 <uuid value=\"0x1002\"/> \
124 </attribute> \124 </sequence> \
125 \125 </attribute> \
126 <attribute id=\"0x0009\"> \126 \
127 <sequence> \127 <attribute id=\"0x0009\"> \
128 <sequence> \128 <sequence> \
129 <uuid value=\"00005005-0000-1000-8000-0002ee000001\"/> \129 <sequence> \
130 <uint16 value=\"0x0100\" name=\"version\"/> \130 <uuid value=\"00005005-0000-1000-8000-0002ee000001\"/> \
131 </sequence> \131 <uint16 value=\"0x0100\" name=\"version\"/> \
132 </sequence> \132 </sequence> \
133 </attribute> \133 </sequence> \
134 \134 </attribute> \
135 <attribute id=\"0x0100\"> \135 \
136 <text value=\"%s\" name=\"name\"/> \136 <attribute id=\"0x0100\"> \
137 </attribute> \137 <text value=\"%s\" name=\"name\"/> \
138 </attribute> \
138</record>"139</record>"
139140
140static const guint8 FTP_TARGET[TARGET_SIZE] = {141static const uint8_t FTP_TARGET[TARGET_SIZE] = {
141 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,142 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
142 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };143 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
143144
144static const guint8 PCSUITE_WHO[PCSUITE_WHO_SIZE] = {145static const uint8_t PCSUITE_WHO[PCSUITE_WHO_SIZE] = {
145 'P','C',' ','S','u','i','t','e' };146 'P','C',' ','S','u','i','t','e' };
146147
147struct ftp_session {148struct ftp_session {
148 struct obex_session *os;149 struct obex_session *os;
149 gchar *folder;150 char *folder;
150};151};
151152
152static void set_folder(struct ftp_session *ftp, const char *new_folder)153static void set_folder(struct ftp_session *ftp, const char *new_folder)
@@ -156,49 +157,32 @@
156 ftp->folder = new_folder ? g_strdup(new_folder) : NULL;157 ftp->folder = new_folder ? g_strdup(new_folder) : NULL;
157}158}
158159
159static gint get_by_type(struct ftp_session *ftp, const gchar *type)160static int get_by_type(struct ftp_session *ftp, const char *type)
160{161{
161 struct obex_session *os = ftp->os;162 struct obex_session *os = ftp->os;
162 const char *capability = obex_get_capability_path(os);163 const char *capability = obex_get_capability_path(os);
163164 const char *name = obex_get_name(os);
164 if (type == NULL)165 char *path;
165 return -ENOENT;166 int err;
166167
167 if (g_str_equal(type, CAP_TYPE))168 if (type == NULL && name == NULL)
168 return obex_stream_start(os, capability, NULL);169 return -EBADR;
169170
170 if (g_str_equal(type, LST_TYPE))171 if (g_strcmp0(type, CAP_TYPE) == 0)
171 return obex_stream_start(os, ftp->folder, os);172 return obex_get_stream_start(os, capability);
172173
173 return -ENOENT;174 if (g_strcmp0(type, LST_TYPE) == 0)
174}175 return obex_get_stream_start(os, ftp->folder);
175176
176static gint ftp_prepare_get(struct ftp_session *ftp, gchar *file)177 path = g_build_filename(ftp->folder, name, NULL);
177{178 err = obex_get_stream_start(os, path);
178 struct obex_session *os = ftp->os;179
179 const char *root_folder = obex_get_root_folder(os);180 g_free(path);
180 gboolean root;181
181182 return err;
182 root = g_str_equal(root_folder, ftp->folder);183}
183184
184 if (!root || !obex_get_symlinks(os)) {185static void *ftp_connect(struct obex_session *os, int *err)
185 struct stat dstat;
186 gint err;
187
188 if (lstat(file, &dstat) < 0) {
189 err = -errno;
190 debug("lstat: %s(%d)", strerror(errno), errno);
191 return err;
192 }
193
194 if (S_ISLNK(dstat.st_mode))
195 return -EPERM;
196 }
197
198 return obex_stream_start(os, file, NULL);
199}
200
201static gpointer ftp_connect(struct obex_session *os, int *err)
202{186{
203 struct ftp_session *ftp;187 struct ftp_session *ftp;
204 const char *root_folder;188 const char *root_folder;
@@ -218,43 +202,28 @@
218}202}
219203
220static int ftp_get(struct obex_session *os, obex_object_t *obj,204static int ftp_get(struct obex_session *os, obex_object_t *obj,
221 gpointer user_data)205 gboolean *stream, void *user_data)
222{206{
223 struct ftp_session *ftp = user_data;207 struct ftp_session *ftp = user_data;
224 const char *type = obex_get_type(os);208 const char *type = obex_get_type(os);
225 const char *name = obex_get_name(os);209 int ret;
226 gint err;210
227 gchar *path;211 if (ftp->folder == NULL)
228212 return -ENOENT;
229 if (ftp->folder == NULL) {213
230 err = -ENOENT;214 ret = get_by_type(ftp, type);
231 goto fail;215 if (ret < 0)
232 }216 return ret;
233217
234 err = get_by_type(ftp, type);218 if (stream)
235 if (err < 0) {219 *stream = TRUE;
236 if (!name)
237 goto fail;
238
239 path = g_build_filename(ftp->folder, name, NULL);
240
241 err = ftp_prepare_get(ftp, path);
242
243 g_free(path);
244
245 if (err < 0)
246 goto fail;
247 }
248220
249 return 0;221 return 0;
250
251fail:
252 return err;
253}222}
254223
255static gint ftp_delete(struct ftp_session *ftp, const char *name)224static int ftp_delete(struct ftp_session *ftp, const char *name)
256{225{
257 gchar *path;226 char *path;
258 int ret = 0;227 int ret = 0;
259228
260 if (!(ftp->folder && name))229 if (!(ftp->folder && name))
@@ -270,26 +239,29 @@
270 return ret;239 return ret;
271}240}
272241
273static gint ftp_chkput(struct obex_session *os, gpointer user_data)242static int ftp_chkput(struct obex_session *os, void *user_data)
274{243{
275 struct ftp_session *ftp = user_data;244 struct ftp_session *ftp = user_data;
276 const gchar *name = obex_get_name(os);245 const char *name = obex_get_name(os);
277 gchar *path;246 char *path;
278 int ret;247 int ret;
279248
249 if (name == NULL)
250 return -EBADR;
251
280 if (obex_get_size(os) == OBJECT_SIZE_DELETE)252 if (obex_get_size(os) == OBJECT_SIZE_DELETE)
281 return 0;253 return 0;
282254
283 path = g_build_filename(ftp->folder, name, NULL);255 path = g_build_filename(ftp->folder, name, NULL);
284256
285 ret = obex_prepare_put(os, path);257 ret = obex_put_stream_start(os, path);
286258
287 g_free(path);259 g_free(path);
288260
289 return ret;261 return ret;
290}262}
291263
292static int ftp_put(struct obex_session *os, gpointer user_data)264static int ftp_put(struct obex_session *os, void *user_data)
293{265{
294 struct ftp_session *ftp = user_data;266 struct ftp_session *ftp = user_data;
295 const char *name = obex_get_name(os);267 const char *name = obex_get_name(os);
@@ -308,12 +280,12 @@
308}280}
309281
310static int ftp_setpath(struct obex_session *os, obex_object_t *obj,282static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
311 gpointer user_data)283 void *user_data)
312{284{
313 struct ftp_session *ftp = user_data;285 struct ftp_session *ftp = user_data;
314 const gchar *root_folder, *name;286 const char *root_folder, *name;
315 guint8 *nonhdr;287 uint8_t *nonhdr;
316 gchar *fullname;288 char *fullname;
317 struct stat dstat;289 struct stat dstat;
318 gboolean root;290 gboolean root;
319 int err;291 int err;
@@ -370,11 +342,13 @@
370 err = lstat(fullname, &dstat);342 err = lstat(fullname, &dstat);
371343
372 if (err < 0) {344 if (err < 0) {
373 int err = errno;345 err = -errno;
346
347 if (err == -ENOENT)
348 goto not_found;
349
374 debug("%s: %s(%d)", root ? "stat" : "lstat",350 debug("%s: %s(%d)", root ? "stat" : "lstat",
375 strerror(err), err);351 strerror(-err), -err);
376 if (err == ENOENT)
377 goto not_found;
378352
379 goto done;353 goto done;
380 }354 }
@@ -395,10 +369,12 @@
395 }369 }
396370
397 if (mkdir(fullname, 0755) < 0) {371 if (mkdir(fullname, 0755) < 0) {
398 err = -EPERM;372 err = -errno;
373 debug("mkdir: %s(%d)", strerror(-err), -err);
399 goto done;374 goto done;
400 }375 }
401376
377 err = 0;
402 set_folder(ftp, fullname);378 set_folder(ftp, fullname);
403379
404done:380done:
@@ -406,7 +382,7 @@
406 return err;382 return err;
407}383}
408384
409static void ftp_disconnect(struct obex_session *os, gpointer user_data)385static void ftp_disconnect(struct obex_session *os, void *user_data)
410{386{
411 struct ftp_session *ftp = user_data;387 struct ftp_session *ftp = user_data;
412388
@@ -416,7 +392,7 @@
416 g_free(ftp);392 g_free(ftp);
417}393}
418394
419struct obex_service_driver pcsuite = {395static struct obex_service_driver pcsuite = {
420 .name = "Nokia OBEX PC Suite Services",396 .name = "Nokia OBEX PC Suite Services",
421 .service = OBEX_PCSUITE,397 .service = OBEX_PCSUITE,
422 .channel = PCSUITE_CHANNEL,398 .channel = PCSUITE_CHANNEL,
@@ -433,7 +409,7 @@
433 .disconnect = ftp_disconnect409 .disconnect = ftp_disconnect
434};410};
435411
436struct obex_service_driver ftp = {412static struct obex_service_driver ftp = {
437 .name = "File Transfer server",413 .name = "File Transfer server",
438 .service = OBEX_FTP,414 .service = OBEX_FTP,
439 .channel = FTP_CHANNEL,415 .channel = FTP_CHANNEL,
440416
=== added file 'plugins/nokia-backup.c'
--- plugins/nokia-backup.c 1970-01-01 00:00:00 +0000
+++ plugins/nokia-backup.c 2010-06-15 19:18:33 +0000
@@ -0,0 +1,295 @@
1/*
2 *
3 * OBEX Server
4 *
5 * Copyright (C) 2010 Nokia Corporation
6 * Copyright (C) 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 <stdio.h>
30#include <errno.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34#include <dirent.h>
35#include <sys/stat.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <sys/statvfs.h>
39#include <fcntl.h>
40#include <wait.h>
41
42#include <glib.h>
43#include "gdbus.h"
44
45
46#include <openobex/obex.h>
47#include <openobex/obex_const.h>
48
49#include "plugin.h"
50#include "logging.h"
51#include "obex.h"
52#include "mimetype.h"
53#include "service.h"
54
55#define BACKUP_BUS_NAME "com.nokia.backup.plugin"
56#define BACKUP_PATH "/com/nokia/backup"
57#define BACKUP_PLUGIN_INTERFACE "com.nokia.backup.plugin"
58#define BACKUP_DBUS_TIMEOUT (1000 * 60 * 15)
59
60static const uint8_t FTP_TARGET[TARGET_SIZE] = {
61 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
62 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
63
64struct backup_object{
65 gchar *cmd;
66 int fd;
67 int oflag;
68 int error_code;
69 mode_t mode;
70 DBusPendingCall *pending_call;
71 DBusConnection *conn;
72};
73
74static void on_backup_dbus_notify(DBusPendingCall *pending_call,
75 void *user_data)
76{
77 struct backup_object *obj = user_data;
78 DBusMessage *reply;
79 const char *filename;
80 int error_code;
81
82 debug("backup: Notification received for pending call - %s", obj->cmd);
83
84 reply = dbus_pending_call_steal_reply(pending_call);
85
86 if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32,
87 &error_code, DBUS_TYPE_STRING,
88 &filename, DBUS_TYPE_INVALID)) {
89
90 obj->error_code = error_code;
91
92 if (filename) {
93 debug("backup: Notification - file path = %s,"
94 "error_code = %d", filename,
95 error_code);
96 if (error_code == 0)
97 obj->fd = open(filename,obj->oflag,obj->mode);
98 }
99
100 } else
101 debug("backup: Notification timed out or connection got closed");
102
103 if (reply)
104 dbus_message_unref(reply);
105
106 dbus_pending_call_unref(pending_call);
107 obj->pending_call = NULL;
108 dbus_connection_unref(obj->conn);
109 obj->conn = NULL;
110
111 if (obj->fd >= 0) {
112 debug("backup: File opened, setting io flags, cmd = %s",
113 obj->cmd);
114 if (obj->oflag == O_RDONLY)
115 obex_object_set_io_flags(user_data, G_IO_IN, 0);
116 else
117 obex_object_set_io_flags(user_data, G_IO_OUT, 0);
118 } else {
119 debug("backup: File open error, setting io error, cmd = %s",
120 obj->cmd);
121 obex_object_set_io_flags(user_data, G_IO_ERR, -EPERM);
122 }
123}
124
125static gboolean send_backup_dbus_message(const char *oper,
126 struct backup_object *obj,
127 size_t *size)
128{
129 DBusConnection *conn;
130 DBusMessage *msg;
131 DBusPendingCall *pending_call;
132 gboolean ret = FALSE;
133 dbus_uint32_t file_size;
134
135 file_size = size ? *size : 0;
136
137 conn = g_dbus_setup_bus(DBUS_BUS_SESSION, NULL, NULL);
138
139 if (conn == NULL)
140 return FALSE;
141
142 msg = dbus_message_new_method_call(BACKUP_BUS_NAME, BACKUP_PATH,
143 BACKUP_PLUGIN_INTERFACE,
144 "request");
145 if (msg == NULL) {
146 dbus_connection_unref(conn);
147 return FALSE;
148 }
149
150 dbus_message_append_args(msg, DBUS_TYPE_STRING, &oper,
151 DBUS_TYPE_STRING, &obj->cmd,
152 DBUS_TYPE_INT32, &file_size,
153 DBUS_TYPE_INVALID);
154
155 ret = dbus_connection_send_with_reply(conn, msg, &pending_call,
156 BACKUP_DBUS_TIMEOUT);
157
158 dbus_message_unref(msg);
159
160 if (ret && (strcmp(oper, "open") == 0)) {
161 obj->conn = conn;
162 obj->pending_call = pending_call;
163 ret = dbus_pending_call_set_notify(pending_call,
164 on_backup_dbus_notify,
165 obj, NULL);
166 } else {
167 dbus_pending_call_unref(pending_call);
168 dbus_connection_unref(conn);
169 }
170
171 return ret;
172}
173
174static void *backup_open(const char *name, int oflag, mode_t mode,
175 void *context, size_t *size, int *err)
176{
177 struct backup_object *obj = g_new0(struct backup_object, 1);
178
179 debug("backup: open(), cmd = %s", name);
180
181 obj->cmd = g_path_get_basename(name);
182 obj->oflag = oflag;
183 obj->mode = mode;
184 obj->fd = -1;
185 obj->pending_call = NULL;
186 obj->conn = NULL;
187 obj->error_code = 0;
188
189 if (send_backup_dbus_message("open", obj, size) == FALSE) {
190 g_free(obj);
191 obj = NULL;
192 }
193
194 if (err)
195 *err = 0;
196
197 return obj;
198}
199
200static int backup_close(void *object)
201{
202 struct backup_object *obj = object;
203 size_t size = 0;
204
205 debug("backup: close(), cmd = %s", obj->cmd);
206
207 if (obj->fd != -1)
208 close(obj->fd);
209
210 if (obj->pending_call) {
211 dbus_pending_call_cancel(obj->pending_call);
212 dbus_pending_call_unref(obj->pending_call);
213 dbus_connection_unref(obj->conn);
214 }
215
216 send_backup_dbus_message("close", obj, &size);
217
218 g_free(obj->cmd);
219 g_free(obj);
220
221 return 0;
222}
223
224static ssize_t backup_read(void *object, void *buf, size_t count, uint8_t *hi)
225{
226 struct backup_object *obj = object;
227 ssize_t ret = 0;
228
229 *hi = OBEX_HDR_BODY;
230
231 if (obj->pending_call) {
232 debug("backup: read(), cmd = %s, IN WAITING STAGE", obj->cmd);
233 return -EAGAIN;
234 }
235
236 if (obj->fd != -1) {
237 debug("backup: read(), cmd = %s, READING DATA", obj->cmd);
238 ret = read(obj->fd, buf, count);
239 if (ret < 0)
240 ret = -errno;
241 } else {
242 debug("backup: read(), cmd = %s, PERMANENT FAILURE", obj->cmd);
243 ret = obj->error_code?(-obj->error_code):(-ENOENT);
244 }
245
246 return ret;
247}
248
249static ssize_t backup_write(void *object, const void *buf, size_t count)
250{
251 struct backup_object *obj = object;
252 ssize_t ret = 0;
253
254 if (obj->pending_call) {
255 debug("backup: write(), cmd = %s, IN WAITING STAGE", obj->cmd);
256 return -EAGAIN;
257 }
258
259 if (obj->fd != -1) {
260 ret = write(obj->fd, buf, count);
261
262 debug("backup: write(), cmd = %s, WRITTING", obj->cmd);
263
264 if (ret < 0) {
265 debug("backup: write() error, cmd = %s", obj->cmd);
266 ret = -errno;
267 }
268 } else {
269 debug("backup: write() error, cmd = %s", obj->cmd);
270 ret = obj->error_code ? -obj->error_code : -ENOENT;
271 }
272
273 return ret;
274}
275
276static struct obex_mime_type_driver backup = {
277 .target = FTP_TARGET,
278 .mimetype = "application/vnd.nokia-backup",
279 .open = backup_open,
280 .close = backup_close,
281 .read = backup_read,
282 .write = backup_write,
283};
284
285static int backup_init(void)
286{
287 return obex_mime_type_driver_register(&backup);
288}
289
290static void backup_exit(void)
291{
292 obex_mime_type_driver_unregister(&backup);
293}
294
295OBEX_PLUGIN_DEFINE(backup, backup_init, backup_exit)
0296
=== modified file 'plugins/opp.c'
--- plugins/opp.c 2010-04-27 04:17:15 +0000
+++ plugins/opp.c 2010-06-15 19:18:33 +0000
@@ -27,6 +27,7 @@
27#endif27#endif
2828
29#include <errno.h>29#include <errno.h>
30#include <string.h>
3031
31#include <openobex/obex.h>32#include <openobex/obex.h>
32#include <openobex/obex_const.h>33#include <openobex/obex_const.h>
@@ -44,56 +45,56 @@
4445
45#define OPP_CHANNEL 946#define OPP_CHANNEL 9
46#define OPP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \47#define OPP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
47<record> \48<record> \
48 <attribute id=\"0x0001\"> \49 <attribute id=\"0x0001\"> \
49 <sequence> \50 <sequence> \
50 <uuid value=\"0x1105\"/> \51 <uuid value=\"0x1105\"/> \
51 </sequence> \52 </sequence> \
52 </attribute> \53 </attribute> \
53 \54 \
54 <attribute id=\"0x0004\"> \55 <attribute id=\"0x0004\"> \
55 <sequence> \56 <sequence> \
56 <sequence> \57 <sequence> \
57 <uuid value=\"0x0100\"/> \58 <uuid value=\"0x0100\"/> \
58 </sequence> \59 </sequence> \
59 <sequence> \60 <sequence> \
60 <uuid value=\"0x0003\"/> \61 <uuid value=\"0x0003\"/> \
61 <uint8 value=\"%u\" name=\"channel\"/> \62 <uint8 value=\"%u\" name=\"channel\"/> \
62 </sequence> \63 </sequence> \
63 <sequence> \64 <sequence> \
64 <uuid value=\"0x0008\"/> \65 <uuid value=\"0x0008\"/> \
65 </sequence> \66 </sequence> \
66 </sequence> \67 </sequence> \
67 </attribute> \68 </attribute> \
68 \69 \
69 <attribute id=\"0x0009\"> \70 <attribute id=\"0x0009\"> \
70 <sequence> \71 <sequence> \
71 <sequence> \72 <sequence> \
72 <uuid value=\"0x1105\"/> \73 <uuid value=\"0x1105\"/> \
73 <uint16 value=\"0x0100\" name=\"version\"/> \74 <uint16 value=\"0x0100\" name=\"version\"/> \
74 </sequence> \75 </sequence> \
75 </sequence> \76 </sequence> \
76 </attribute> \77 </attribute> \
77 \78 \
78 <attribute id=\"0x0100\"> \79 <attribute id=\"0x0100\"> \
79 <text value=\"%s\" name=\"name\"/> \80 <text value=\"%s\" name=\"name\"/> \
80 </attribute> \81 </attribute> \
81 \82 \
82 <attribute id=\"0x0303\"> \83 <attribute id=\"0x0303\"> \
83 <sequence> \84 <sequence> \
84 <uint8 value=\"0x01\"/> \85 <uint8 value=\"0x01\"/> \
85 <uint8 value=\"0x01\"/> \86 <uint8 value=\"0x01\"/> \
86 <uint8 value=\"0x02\"/> \87 <uint8 value=\"0x02\"/> \
87 <uint8 value=\"0x03\"/> \88 <uint8 value=\"0x03\"/> \
88 <uint8 value=\"0x04\"/> \89 <uint8 value=\"0x04\"/> \
89 <uint8 value=\"0x05\"/> \90 <uint8 value=\"0x05\"/> \
90 <uint8 value=\"0x06\"/> \91 <uint8 value=\"0x06\"/> \
91 <uint8 value=\"0xff\"/> \92 <uint8 value=\"0xff\"/> \
92 </sequence> \93 </sequence> \
93 </attribute> \94 </attribute> \
94</record>"95</record>"
9596
96static gpointer opp_connect(struct obex_session *os, int *err)97static void *opp_connect(struct obex_session *os, int *err)
97{98{
98 manager_register_transfer(os);99 manager_register_transfer(os);
99100
@@ -103,17 +104,17 @@
103 return NULL;104 return NULL;
104}105}
105106
106static void opp_progress(struct obex_session *os, gpointer user_data)107static void opp_progress(struct obex_session *os, void *user_data)
107{108{
108 manager_emit_transfer_progress(os);109 manager_emit_transfer_progress(os);
109}110}
110111
111static gint opp_chkput(struct obex_session *os, gpointer user_data)112static int opp_chkput(struct obex_session *os, void *user_data)
112{113{
113 gchar *folder, *name;114 char *folder, *name;
114 gchar *path;115 char *path;
115 gint32 time;116 int32_t time;
116 gint ret;117 int ret;
117118
118 if (obex_get_size(os) == OBJECT_SIZE_DELETE)119 if (obex_get_size(os) == OBJECT_SIZE_DELETE)
119 return -EINVAL;120 return -EINVAL;
@@ -136,11 +137,17 @@
136 name = g_strdup(obex_get_name(os));137 name = g_strdup(obex_get_name(os));
137138
138skip_auth:139skip_auth:
140 if (name == NULL || strlen(name) == 0)
141 return -EBADR;
142
143 if (g_strcmp0(name, obex_get_name(os)) != 0)
144 obex_set_name(os, name);
145
139 path = g_build_filename(folder, name, NULL);146 path = g_build_filename(folder, name, NULL);
140147
141 manager_emit_transfer_started(os);148 manager_emit_transfer_started(os);
142149
143 ret = obex_prepare_put(os, path);150 ret = obex_put_stream_start(os, path);
144151
145 g_free(path);152 g_free(path);
146 g_free(folder);153 g_free(folder);
@@ -149,7 +156,7 @@
149 return ret;156 return ret;
150}157}
151158
152static int opp_put(struct obex_session *os, gpointer user_data)159static int opp_put(struct obex_session *os, void *user_data)
153{160{
154 const char *name = obex_get_name(os);161 const char *name = obex_get_name(os);
155 const char *folder = obex_get_root_folder(os);162 const char *folder = obex_get_root_folder(os);
@@ -164,7 +171,7 @@
164}171}
165172
166static int opp_get(struct obex_session *os, obex_object_t *obj,173static int opp_get(struct obex_session *os, obex_object_t *obj,
167 gpointer user_data)174 gboolean *stream, void *user_data)
168{175{
169 const char *type;176 const char *type;
170177
@@ -177,26 +184,29 @@
177 return -EPERM;184 return -EPERM;
178185
179 if (g_str_equal(type, VCARD_TYPE)) {186 if (g_str_equal(type, VCARD_TYPE)) {
180 if (obex_stream_start(os, VCARD_FILE, NULL) < 0)187 if (obex_get_stream_start(os, VCARD_FILE) < 0)
181 return -ENOENT;188 return -ENOENT;
182189
183 } else190 } else
184 return -EPERM;191 return -EPERM;
185192
193 if (stream)
194 *stream = TRUE;
195
186 return 0;196 return 0;
187}197}
188198
189static void opp_disconnect(struct obex_session *os, gpointer user_data)199static void opp_disconnect(struct obex_session *os, void *user_data)
190{200{
191 manager_unregister_transfer(os);201 manager_unregister_transfer(os);
192}202}
193203
194static void opp_reset(struct obex_session *os, gpointer user_data)204static void opp_reset(struct obex_session *os, void *user_data)
195{205{
196 manager_emit_transfer_completed(os);206 manager_emit_transfer_completed(os);
197}207}
198208
199struct obex_service_driver driver = {209static struct obex_service_driver driver = {
200 .name = "Object Push server",210 .name = "Object Push server",
201 .service = OBEX_OPP,211 .service = OBEX_OPP,
202 .channel = OPP_CHANNEL,212 .channel = OPP_CHANNEL,
203213
=== modified file 'plugins/pbap.c'
--- plugins/pbap.c 2010-04-27 04:17:15 +0000
+++ plugins/pbap.c 2010-06-15 19:18:33 +0000
@@ -26,11 +26,13 @@
26#include <config.h>26#include <config.h>
27#endif27#endif
2828
29#include <stdio.h>
29#include <string.h>30#include <string.h>
30#include <errno.h>31#include <errno.h>
31#include <glib.h>32#include <glib.h>
32#include <stdlib.h>33#include <stdlib.h>
33#include <unistd.h>34#include <unistd.h>
35#include <arpa/inet.h>
34#include <sys/types.h>36#include <sys/types.h>
35#include <sys/stat.h>37#include <sys/stat.h>
36#include <fcntl.h>38#include <fcntl.h>
@@ -71,87 +73,382 @@
71#define PHONEBOOKSIZE_LEN 273#define PHONEBOOKSIZE_LEN 2
72#define NEWMISSEDCALLS_LEN 174#define NEWMISSEDCALLS_LEN 1
7375
74#define MCH "telecom/mch.vcf"
75#define SIM1_MCH "SIM1/telecom/mch.vcf"
76
77#define DEFAULT_COUNT 65535
78
79#define APPARAM_HDR_SIZE 2
80
81#define PBAP_CHANNEL 1576#define PBAP_CHANNEL 15
8277
83#define PBAP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \78#define PBAP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
84<record> \79<record> \
85 <attribute id=\"0x0001\"> \80 <attribute id=\"0x0001\"> \
86 <sequence> \81 <sequence> \
87 <uuid value=\"0x112f\"/> \82 <uuid value=\"0x112f\"/> \
88 </sequence> \83 </sequence> \
89 </attribute> \84 </attribute> \
90 \85 \
91 <attribute id=\"0x0004\"> \86 <attribute id=\"0x0004\"> \
92 <sequence> \87 <sequence> \
93 <sequence> \88 <sequence> \
94 <uuid value=\"0x0100\"/> \89 <uuid value=\"0x0100\"/> \
95 </sequence> \90 </sequence> \
96 <sequence> \91 <sequence> \
97 <uuid value=\"0x0003\"/> \92 <uuid value=\"0x0003\"/> \
98 <uint8 value=\"%u\" name=\"channel\"/> \93 <uint8 value=\"%u\" name=\"channel\"/> \
99 </sequence> \94 </sequence> \
100 <sequence> \95 <sequence> \
101 <uuid value=\"0x0008\"/> \96 <uuid value=\"0x0008\"/> \
102 </sequence> \97 </sequence> \
103 </sequence> \98 </sequence> \
104 </attribute> \99 </attribute> \
105 \100 \
106 <attribute id=\"0x0009\"> \101 <attribute id=\"0x0009\"> \
107 <sequence> \102 <sequence> \
108 <sequence> \103 <sequence> \
109 <uuid value=\"0x1130\"/> \104 <uuid value=\"0x1130\"/> \
110 <uint16 value=\"0x0100\" name=\"version\"/> \105 <uint16 value=\"0x0100\" name=\"version\"/> \
111 </sequence> \106 </sequence> \
112 </sequence> \107 </sequence> \
113 </attribute> \108 </attribute> \
114 \109 \
115 <attribute id=\"0x0100\"> \110 <attribute id=\"0x0100\"> \
116 <text value=\"%s\" name=\"name\"/> \111 <text value=\"%s\" name=\"name\"/> \
117 </attribute> \112 </attribute> \
118 \113 \
119 <attribute id=\"0x0314\"> \114 <attribute id=\"0x0314\"> \
120 <uint8 value=\"0x01\"/> \115 <uint8 value=\"0x01\"/> \
121 </attribute> \116 </attribute> \
122</record>"117</record>"
123118
124struct aparam_header {119struct aparam_header {
125 uint8_t tag;120 uint8_t tag;
126 uint8_t len;121 uint8_t len;
127 uint8_t val[0];122 uint8_t val[0];
128} __attribute__ ((packed));123} __attribute__ ((packed));
129124
125struct cache {
126 gboolean valid;
127 uint32_t index;
128 char *folder;
129 GSList *entries;
130};
131
132struct cache_entry {
133 uint32_t handle;
134 char *id;
135 char *name;
136 char *sound;
137 char *tel;
138};
139
130struct pbap_session {140struct pbap_session {
131 struct obex_session *os;
132 struct apparam_field *params;141 struct apparam_field *params;
133 gchar *folder;142 char *folder;
143 uint32_t find_handle;
134 GString *buffer;144 GString *buffer;
145 struct cache cache;
135};146};
136147
137static const guint8 PBAP_TARGET[TARGET_SIZE] = {148static const uint8_t PBAP_TARGET[TARGET_SIZE] = {
138 0x79, 0x61, 0x35, 0xF0, 0xF0, 0xC5, 0x11, 0xD8,149 0x79, 0x61, 0x35, 0xF0, 0xF0, 0xC5, 0x11, 0xD8,
139 0x09, 0x66, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66 };150 0x09, 0x66, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66 };
140151
141static void set_folder(struct pbap_session *pbap, const char *new_folder)152typedef int (*cache_entry_find_f) (const struct cache_entry *entry,
142{153 const char *value);
143 g_free(pbap->folder);154
144155static void cache_entry_free(struct cache_entry *entry)
145 pbap->folder = new_folder ? g_strdup(new_folder) : NULL;156{
146}157 g_free(entry->id);
147158 g_free(entry->name);
148static struct apparam_field *parse_aparam(const guint8 *buffer, guint32 hlen)159 g_free(entry->sound);
160 g_free(entry->tel);
161 g_free(entry);
162}
163
164static gboolean entry_name_find(const struct cache_entry *entry,
165 const char *value)
166{
167 char *name;
168 gboolean ret;
169
170 if (!entry->name)
171 return FALSE;
172
173 if (strlen(value) == 0)
174 return TRUE;
175
176 name = g_utf8_strdown(entry->name, -1);
177 ret = (g_strstr_len(name, -1, value) ? TRUE : FALSE);
178 g_free(name);
179
180 return ret;
181}
182
183static gboolean entry_sound_find(const struct cache_entry *entry,
184 const char *value)
185{
186 if (!entry->sound)
187 return FALSE;
188
189 return (g_strstr_len(entry->sound, -1, value) ? TRUE : FALSE);
190}
191
192static gboolean entry_tel_find(const struct cache_entry *entry,
193 const char *value)
194{
195 if (!entry->tel)
196 return FALSE;
197
198 return (g_strstr_len(entry->tel, -1, value) ? TRUE : FALSE);
199}
200
201static const char *cache_find(struct cache *cache, uint32_t handle)
202{
203 GSList *l;
204
205 for (l = cache->entries; l; l = l->next) {
206 struct cache_entry *entry = l->data;
207
208 if (entry->handle == handle)
209 return entry->id;
210 }
211
212 return NULL;
213}
214
215static void cache_clear(struct cache *cache)
216{
217 g_free(cache->folder);
218 g_slist_foreach(cache->entries, (GFunc) cache_entry_free, NULL);
219 g_slist_free(cache->entries);
220 cache->entries = NULL;
221}
222
223static void phonebook_size_result(const char *buffer, size_t bufsize,
224 int vcards, int missed, void *user_data)
225{
226 struct pbap_session *pbap = user_data;
227 char aparam[4];
228 struct aparam_header *hdr = (struct aparam_header *) aparam;
229 uint16_t phonebooksize;
230
231 DBG("vcards %d", vcards);
232
233 phonebooksize = htons(vcards);
234
235 hdr->tag = PHONEBOOKSIZE_TAG;
236 hdr->len = PHONEBOOKSIZE_LEN;
237 memcpy(hdr->val, &phonebooksize, sizeof(phonebooksize));
238
239 pbap->buffer = g_string_new_len(aparam, sizeof(aparam));
240
241 obex_object_set_io_flags(pbap, G_IO_IN, 0);
242}
243
244static void query_result(const char *buffer, size_t bufsize, int vcards,
245 int missed, void *user_data)
246{
247 struct pbap_session *pbap = user_data;
248
249 DBG("");
250
251 if (!pbap->buffer)
252 pbap->buffer = g_string_new_len(buffer, bufsize);
253 else
254 pbap->buffer = g_string_append_len(pbap->buffer, buffer,
255 bufsize);
256
257 obex_object_set_io_flags(pbap, G_IO_IN, 0);
258}
259
260static void cache_entry_notify(const char *id, uint32_t handle,
261 const char *name, const char *sound,
262 const char *tel, void *user_data)
263{
264 struct pbap_session *pbap = user_data;
265 struct cache_entry *entry = g_new0(struct cache_entry, 1);
266 struct cache *cache = &pbap->cache;
267
268 if (handle != PHONEBOOK_INVALID_HANDLE)
269 entry->handle = handle;
270 else
271 entry->handle = ++pbap->cache.index;
272
273 entry->id = g_strdup(id);
274 entry->name = g_strdup(name);
275 entry->sound = g_strdup(sound);
276 entry->tel = g_strdup(tel);
277
278 cache->entries = g_slist_append(cache->entries, entry);
279}
280
281static int alpha_sort(gconstpointer a, gconstpointer b)
282{
283 const struct cache_entry *e1 = a;
284 const struct cache_entry *e2 = b;
285
286 return g_strcmp0(e1->name, e2->name);
287}
288
289static int indexed_sort(gconstpointer a, gconstpointer b)
290{
291 const struct cache_entry *e1 = a;
292 const struct cache_entry *e2 = b;
293
294 return (e1->handle - e2->handle);
295}
296
297static int phonetical_sort(gconstpointer a, gconstpointer b)
298{
299 const struct cache_entry *e1 = a;
300 const struct cache_entry *e2 = b;
301
302 /* SOUND attribute is optional. Use Indexed sort if not present. */
303 if (!e1->sound || !e2->sound)
304 return indexed_sort(a, b);
305
306 return g_strcmp0(e1->sound, e2->sound);
307}
308
309static GSList *sort_entries(GSList *l, uint8_t order, uint8_t search_attrib,
310 const char *value)
311{
312 GSList *sorted = NULL;
313 cache_entry_find_f find;
314 GCompareFunc sort;
315 char *searchval;
316
317 /*
318 * Default sorter is "Indexed". Some backends doesn't inform the index,
319 * for this case a sequential internal index is assigned.
320 * 0x00 = indexed
321 * 0x01 = alphanumeric
322 * 0x02 = phonetic
323 */
324 switch (order) {
325 case 0x01:
326 sort = alpha_sort;
327 break;
328 case 0x02:
329 sort = phonetical_sort;
330 break;
331 default:
332 sort = indexed_sort;
333 break;
334 }
335
336 /*
337 * This implementation checks if the given field CONTAINS the
338 * search value(case insensitive). Name is the default field
339 * when the attribute is not provided.
340 */
341 switch (search_attrib) {
342 /* Number */
343 case 1:
344 find = entry_tel_find;
345 break;
346 /* Sound */
347 case 2:
348 find = entry_sound_find;
349 break;
350 default:
351 find = entry_name_find;
352 break;
353 }
354
355 searchval = value ? g_utf8_strdown(value, -1) : NULL;
356 for (; l; l = l->next) {
357 struct cache_entry *entry = l->data;
358
359 if (searchval && !find(entry, (const char *) searchval))
360 continue;
361
362 sorted = g_slist_insert_sorted(sorted, entry, sort);
363 }
364
365 g_free(searchval);
366
367 return sorted;
368}
369
370static void cache_ready_notify(void *user_data)
371{
372 struct pbap_session *pbap = user_data;
373 GSList *sorted;
374 GSList *l;
375 uint16_t max = pbap->params->maxlistcount;
376
377 DBG("");
378
379 if (max == 0) {
380 /* Ignore all other parameter and return PhoneBookSize */
381 char aparam[4];
382 struct aparam_header *hdr = (struct aparam_header *) aparam;
383 uint16_t size = htons(g_slist_length(pbap->cache.entries));
384
385 hdr->tag = PHONEBOOKSIZE_TAG;
386 hdr->len = PHONEBOOKSIZE_LEN;
387 memcpy(hdr->val, &size, sizeof(size));
388
389 pbap->buffer = g_string_new_len(aparam, sizeof(aparam));
390 goto done;
391 }
392 /*
393 * Don't free the sorted list content: this list contains
394 * only the reference for the "real" cache entry.
395 */
396 sorted = sort_entries(pbap->cache.entries, pbap->params->order,
397 pbap->params->searchattrib,
398 (const char *) pbap->params->searchval);
399
400 /* Computing offset considering first entry of the phonebook */
401 l = g_slist_nth(sorted, pbap->params->liststartoffset);
402
403 pbap->buffer = g_string_new(VCARD_LISTING_BEGIN);
404 for (; l && max; l = l->next, max--) {
405 const struct cache_entry *entry = l->data;
406
407 g_string_append_printf(pbap->buffer, VCARD_LISTING_ELEMENT,
408 entry->handle, entry->name);
409 }
410
411 pbap->buffer = g_string_append(pbap->buffer, VCARD_LISTING_END);
412
413 g_slist_free(sorted);
414
415done:
416 if (!pbap->cache.valid) {
417 pbap->cache.valid = TRUE;
418 obex_object_set_io_flags(pbap, G_IO_IN, 0);
419 }
420}
421
422static void cache_entry_done(void *user_data)
423{
424 struct pbap_session *pbap = user_data;
425 const char *id;
426 int ret;
427
428 DBG("");
429
430 pbap->cache.valid = TRUE;
431
432 id = cache_find(&pbap->cache, pbap->find_handle);
433 if (id == NULL) {
434 debug("Entry %d not found on cache", pbap->find_handle);
435 obex_object_set_io_flags(pbap, G_IO_ERR, -ENOENT);
436 return;
437 }
438
439 ret = phonebook_get_entry(pbap->folder, id, pbap->params,
440 query_result, pbap);
441 if (ret < 0)
442 obex_object_set_io_flags(pbap, G_IO_ERR, ret);
443}
444
445static struct apparam_field *parse_aparam(const uint8_t *buffer, uint32_t hlen)
149{446{
150 struct apparam_field *param;447 struct apparam_field *param;
151 struct aparam_header *hdr;448 struct aparam_header *hdr;
152 guint32 len = 0;449 uint64_t val64;
153 guint16 val16;450 uint32_t len = 0;
154 guint64 val64;451 uint16_t val16;
155452
156 param = g_new0(struct apparam_field, 1);453 param = g_new0(struct apparam_field, 1);
157454
@@ -173,6 +470,9 @@
173 param->searchattrib = hdr->val[0];470 param->searchattrib = hdr->val[0];
174 break;471 break;
175 case SEARCHVALUE_TAG:472 case SEARCHVALUE_TAG:
473 if (hdr->len == 0)
474 goto failed;
475
176 param->searchval = g_try_malloc0(hdr->len + 1);476 param->searchval = g_try_malloc0(hdr->len + 1);
177 if (param->searchval)477 if (param->searchval)
178 memcpy(param->searchval, hdr->val, hdr->len);478 memcpy(param->searchval, hdr->val, hdr->len);
@@ -212,6 +512,11 @@
212 len += hdr->len + sizeof(struct aparam_header);512 len += hdr->len + sizeof(struct aparam_header);
213 }513 }
214514
515 DBG("o %x sa %x sv %s fil %" G_GINT64_MODIFIER "x for %x max %x off %x",
516 param->order, param->searchattrib, param->searchval,
517 param->filter, param->format, param->maxlistcount,
518 param->liststartoffset);
519
215 return param;520 return param;
216521
217failed:522failed:
@@ -220,7 +525,7 @@
220 return NULL;525 return NULL;
221}526}
222527
223static gpointer pbap_connect(struct obex_session *os, int *err)528static void *pbap_connect(struct obex_session *os, int *err)
224{529{
225 struct pbap_session *pbap;530 struct pbap_session *pbap;
226531
@@ -228,7 +533,7 @@
228533
229 pbap = g_new0(struct pbap_session, 1);534 pbap = g_new0(struct pbap_session, 1);
230 pbap->folder = g_strdup("/");535 pbap->folder = g_strdup("/");
231 pbap->os = os;536 pbap->find_handle = PHONEBOOK_INVALID_HANDLE;
232537
233 if (err)538 if (err)
234 *err = 0;539 *err = 0;
@@ -237,24 +542,42 @@
237}542}
238543
239static int pbap_get(struct obex_session *os, obex_object_t *obj,544static int pbap_get(struct obex_session *os, obex_object_t *obj,
240 gpointer user_data)545 gboolean *stream, void *user_data)
241{546{
242 struct pbap_session *pbap = user_data;547 struct pbap_session *pbap = user_data;
243 const gchar *type = obex_get_type(os);548 const char *type = obex_get_type(os);
244 const gchar *name = obex_get_name(os);549 const char *name = obex_get_name(os);
245 struct apparam_field *params;550 struct apparam_field *params;
246 const guint8 *buffer;551 const uint8_t *buffer;
247 gchar *path;552 char *path;
248 ssize_t rsize;553 ssize_t rsize;
249 gint ret;554 int ret;
555
556 DBG("name %s type %s pbap %p", name, type, pbap);
250557
251 if (type == NULL)558 if (type == NULL)
252 return -EBADR;559 return -EBADR;
253560
254 if (strcmp(type, PHONEBOOK_TYPE) == 0)561 rsize = obex_aparam_read(os, obj, &buffer);
562 if (rsize < 0)
563 return -EBADR;
564
565 params = parse_aparam(buffer, rsize);
566 if (params == NULL)
567 return -EBADR;
568
569 if (pbap->params) {
570 g_free(pbap->params->searchval);
571 g_free(pbap->params);
572 }
573
574 pbap->params = params;
575
576 if (strcmp(type, PHONEBOOK_TYPE) == 0) {
255 /* Always contains the absolute path */577 /* Always contains the absolute path */
256 path = g_strdup(name);578 path = g_strdup(name);
257 else if (strcmp(type, VCARDLISTING_TYPE) == 0)579 *stream = (params->maxlistcount == 0 ? FALSE : TRUE);
580 } else if (strcmp(type, VCARDLISTING_TYPE) == 0) {
258 /* Always relative */581 /* Always relative */
259 if (!name || strlen(name) == 0)582 if (!name || strlen(name) == 0)
260 /* Current folder */583 /* Current folder */
@@ -263,47 +586,30 @@
263 /* Current folder + relative path */586 /* Current folder + relative path */
264 path = g_build_filename(pbap->folder, name, NULL);587 path = g_build_filename(pbap->folder, name, NULL);
265588
266 else if (strcmp(type, VCARDENTRY_TYPE) == 0)589 *stream = (params->maxlistcount == 0 ? FALSE : TRUE);
267 /* Always relative */590 } else if (strcmp(type, VCARDENTRY_TYPE) == 0) {
268 path = g_build_filename(pbap->folder, name, NULL);591 /* File name only */
269 else592 path = g_strdup(name);
593 *stream = TRUE;
594 } else
270 return -EBADR;595 return -EBADR;
271596
272 rsize = obex_aparam_read(os, obj, &buffer);
273 if (rsize < 0) {
274 ret = -EBADR;
275 goto failed;
276 }
277
278 params = parse_aparam(buffer, rsize);
279 if (params == NULL) {
280 ret = -EBADR;
281 goto failed;
282 }
283
284 if (pbap->params) {
285 g_free(pbap->params->searchval);
286 g_free(pbap->params);
287 }
288
289 pbap->params = params;597 pbap->params = params;
290 ret = obex_stream_start(os, path, pbap);598 ret = obex_get_stream_start(os, path);
291599
292failed:
293 g_free(path);600 g_free(path);
294601
295 return ret;602 return ret;
296}603}
297604
298
299static int pbap_setpath(struct obex_session *os, obex_object_t *obj,605static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
300 gpointer user_data)606 void *user_data)
301{607{
302 struct pbap_session *pbap = user_data;608 struct pbap_session *pbap = user_data;
303 const gchar *name;609 const char *name;
304 guint8 *nonhdr;610 uint8_t *nonhdr;
305 gchar *fullname;611 char *fullname;
306 int ret;612 int err;
307613
308 if (OBEX_ObjectGetNonHdrData(obj, &nonhdr) != 2) {614 if (OBEX_ObjectGetNonHdrData(obj, &nonhdr) != 2) {
309 error("Set path failed: flag and constants not found!");615 error("Set path failed: flag and constants not found!");
@@ -312,24 +618,27 @@
312618
313 name = obex_get_name(os);619 name = obex_get_name(os);
314620
315 ret = phonebook_set_folder(pbap->folder, name, nonhdr[0]);621 DBG("name %s folder %s nonhdr 0x%x%x", name, pbap->folder,
316 if (ret < 0)622 nonhdr[0], nonhdr[1]);
317 return ret;623
318624 fullname = phonebook_set_folder(pbap->folder, name, nonhdr[0], &err);
319 if (!pbap->folder)625 if (err < 0)
320 fullname = g_strdup(name);626 return err;
321 else627
322 fullname = g_build_filename(pbap->folder, name, NULL);628 g_free(pbap->folder);
323629 pbap->folder = fullname;
324 set_folder(pbap, fullname);630
325631 /*
326 g_free(fullname);632 * FIXME: Define a criteria to mark the cache as invalid
633 */
634 pbap->cache.valid = FALSE;
635 pbap->cache.index = 0;
636 cache_clear(&pbap->cache);
327637
328 return 0;638 return 0;
329}639}
330640
331static void pbap_disconnect(struct obex_session *os,641static void pbap_disconnect(struct obex_session *os, void *user_data)
332 gpointer user_data)
333{642{
334 struct pbap_session *pbap = user_data;643 struct pbap_session *pbap = user_data;
335644
@@ -340,18 +649,18 @@
340 g_free(pbap->params);649 g_free(pbap->params);
341 }650 }
342651
652 cache_clear(&pbap->cache);
343 g_free(pbap->folder);653 g_free(pbap->folder);
344 g_free(pbap);654 g_free(pbap);
345}655}
346656
347static gint pbap_chkput(struct obex_session *os,657static int pbap_chkput(struct obex_session *os, void *user_data)
348 gpointer user_data)
349{658{
350 /* Rejects all PUTs */659 /* Rejects all PUTs */
351 return -EINVAL;660 return -EBADR;
352}661}
353662
354struct obex_service_driver pbap = {663static struct obex_service_driver pbap = {
355 .name = "Phonebook Access server",664 .name = "Phonebook Access server",
356 .service = OBEX_PBAP,665 .service = OBEX_PBAP,
357 .channel = PBAP_CHANNEL,666 .channel = PBAP_CHANNEL,
@@ -365,57 +674,189 @@
365 .chkput = pbap_chkput674 .chkput = pbap_chkput
366};675};
367676
368static void query_result(const gchar *buffer, size_t bufsize,677static void *vobject_pull_open(const char *name, int oflag, mode_t mode,
369 gint vcards, gint missed, gpointer user_data)678 void *context, size_t *size, int *err)
370{679{
371 struct pbap_session *pbap = user_data;680 struct pbap_session *pbap = context;
372681 phonebook_cb cb;
373 if (!pbap->buffer)682 int ret;
374 pbap->buffer = g_string_new_len(buffer, bufsize);683
375 else684 DBG("name %s context %p maxlistcount %d", name, context,
376 pbap->buffer = g_string_append_len(pbap->buffer, buffer, bufsize);685 pbap->params->maxlistcount);
377686
378 obex_object_set_io_flags(pbap, G_IO_IN, 0);687 if (oflag != O_RDONLY) {
379}688 ret = -EPERM;
380689 goto fail;
381static gpointer vobject_open(const char *name, int oflag, mode_t mode,690 }
382 gpointer context, size_t *size, int *err)691
383{692 if (pbap->params->maxlistcount == 0)
384 struct pbap_session *pbap = context;693 cb = phonebook_size_result;
385 int ret;694 else
386695 cb = query_result;
387 if (oflag != O_RDONLY) {696
388 ret = -EPERM;697 ret = phonebook_pull(name, pbap->params, cb, pbap);
389 goto fail;698 if (ret < 0)
390 }699 goto fail;
391700
392 ret = phonebook_pull(name, pbap->params, query_result, pbap);701 if (size)
393 if (ret < 0)702 *size = OBJECT_SIZE_UNKNOWN;
394 goto fail;703
395704 return pbap;
396 if (size)705
397 *size = OBJECT_SIZE_UNKNOWN;706fail:
398707 if (err)
399 return pbap;708 *err = ret;
400709
401fail:710 return NULL;
402 if (err)711}
403 *err = ret;712
404713static void *vobject_list_open(const char *name, int oflag, mode_t mode,
405 return NULL;714 void *context, size_t *size, int *err)
406}715{
407716 struct pbap_session *pbap = context;
408static ssize_t vobject_read(gpointer object, void *buf, size_t count)717 int ret;
409{718
410 struct pbap_session *pbap = object;719 DBG("name %s context %p valid %d", name, context, pbap->cache.valid);
411720
412 if (pbap->buffer)721 if (oflag != O_RDONLY) {
413 return string_read(pbap->buffer, buf, count);722 ret = -EPERM;
414723 goto fail;
415 return -EAGAIN;724 }
416}725
417726 /* PullvCardListing always get the contacts from the cache */
418static int vobject_close(gpointer object)727
728 if (pbap->cache.valid) {
729 cache_ready_notify(pbap);
730 goto done;
731 }
732
733 ret = phonebook_create_cache(name,
734 cache_entry_notify, cache_ready_notify, pbap);
735
736 if (ret < 0)
737 goto fail;
738
739done:
740 if (size)
741 *size = OBJECT_SIZE_UNKNOWN;
742
743 return pbap;
744
745fail:
746 if (err)
747 *err = ret;
748
749 return NULL;
750}
751
752static void *vobject_vcard_open(const char *name, int oflag, mode_t mode,
753 void *context, size_t *size, int *err)
754{
755 struct pbap_session *pbap = context;
756 const char *id;
757 uint32_t handle;
758 int ret;
759
760 DBG("name %s context %p valid %d", name, context, pbap->cache.valid);
761
762 if (oflag != O_RDONLY) {
763 ret = -EPERM;
764 goto fail;
765 }
766
767 if (sscanf(name, "%u.vcf", &handle) != 1) {
768 ret = -EBADR;
769 goto fail;
770 }
771
772 if (pbap->cache.valid == FALSE) {
773 pbap->find_handle = handle;
774 ret = phonebook_create_cache(pbap->folder, cache_entry_notify,
775 cache_entry_done, pbap);
776 goto done;
777 }
778
779 id = cache_find(&pbap->cache, handle);
780 if (!id) {
781 ret = -ENOENT;
782 goto fail;
783 }
784
785 ret = phonebook_get_entry(pbap->folder, id, pbap->params, query_result,
786 pbap);
787
788done:
789 if (ret < 0)
790 goto fail;
791
792 if (size)
793 *size = OBJECT_SIZE_UNKNOWN;
794
795 return pbap;
796
797fail:
798 if (err)
799 *err = ret;
800
801 return NULL;
802}
803
804static ssize_t vobject_pull_read(void *object, void *buf, size_t count,
805 uint8_t *hi)
806{
807 struct pbap_session *pbap = object;
808
809 DBG("buffer %p maxlistcount %d", pbap->buffer,
810 pbap->params->maxlistcount);
811
812 if (!pbap->buffer)
813 return -EAGAIN;
814
815 /* PhoneBookSize */
816 if (pbap->params->maxlistcount == 0)
817 *hi = OBEX_HDR_APPARAM;
818 else
819 /* Stream data */
820 *hi = OBEX_HDR_BODY;
821
822 return string_read(pbap->buffer, buf, count);
823}
824
825static ssize_t vobject_list_read(void *object, void *buf, size_t count,
826 uint8_t *hi)
827{
828 struct pbap_session *pbap = object;
829
830 DBG("valid %d maxlistcount %d", pbap->cache.valid,
831 pbap->params->maxlistcount);
832
833 /* Backend still busy reading contacts */
834 if (!pbap->cache.valid)
835 return -EAGAIN;
836
837 if (pbap->params->maxlistcount == 0)
838 *hi = OBEX_HDR_APPARAM;
839 else
840 *hi = OBEX_HDR_BODY;
841
842 return string_read(pbap->buffer, buf, count);
843}
844
845static ssize_t vobject_vcard_read(void *object, void *buf, size_t count,
846 uint8_t *hi)
847{
848 struct pbap_session *pbap = object;
849
850 DBG("buffer %p", pbap->buffer);
851
852 if (!pbap->buffer)
853 return -EAGAIN;
854
855 *hi = OBEX_HDR_BODY;
856 return string_read(pbap->buffer, buf, count);
857}
858
859static int vobject_close(void *object)
419{860{
420 struct pbap_session *pbap = object;861 struct pbap_session *pbap = object;
421862
@@ -427,28 +868,28 @@
427 return 0;868 return 0;
428}869}
429870
430struct obex_mime_type_driver mime_pull = {871static struct obex_mime_type_driver mime_pull = {
431 .target = PBAP_TARGET,872 .target = PBAP_TARGET,
432 .mimetype = "x-bt/phonebook",873 .mimetype = "x-bt/phonebook",
433 .open = vobject_open,874 .open = vobject_pull_open,
434 .close = vobject_close,875 .close = vobject_close,
435 .read = vobject_read,876 .read = vobject_pull_read,
436};877};
437878
438struct obex_mime_type_driver mime_list = {879static struct obex_mime_type_driver mime_list = {
439 .target = PBAP_TARGET,880 .target = PBAP_TARGET,
440 .mimetype = "x-bt/vcard-listing",881 .mimetype = "x-bt/vcard-listing",
441 .open = vobject_open,882 .open = vobject_list_open,
442 .close = vobject_close,883 .close = vobject_close,
443 .read = vobject_read,884 .read = vobject_list_read,
444};885};
445886
446struct obex_mime_type_driver mime_vcard = {887static struct obex_mime_type_driver mime_vcard = {
447 .target = PBAP_TARGET,888 .target = PBAP_TARGET,
448 .mimetype = "x-bt/vcard",889 .mimetype = "x-bt/vcard",
449 .open = vobject_open,890 .open = vobject_vcard_open,
450 .close = vobject_close,891 .close = vobject_close,
451 .read = vobject_read,892 .read = vobject_vcard_read,
452};893};
453894
454static int pbap_init(void)895static int pbap_init(void)
455896
=== modified file 'plugins/phonebook-dummy.c'
--- plugins/phonebook-dummy.c 2010-04-27 04:17:15 +0000
+++ plugins/phonebook-dummy.c 2010-06-15 19:18:33 +0000
@@ -26,61 +26,513 @@
26#include <config.h>26#include <config.h>
27#endif27#endif
2828
29#include <dirent.h>
30#include <errno.h>
31#include <stdio.h>
32#include <stdint.h>
29#include <string.h>33#include <string.h>
30#include <glib.h>34#include <glib.h>
35#include <stdlib.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <fcntl.h>
39#include <unistd.h>
40#include <libical/ical.h>
41#include <libical/vobject.h>
42#include <libical/vcc.h>
3143
32#include "logging.h"44#include "logging.h"
33#include "phonebook.h"45#include "phonebook.h"
3446
35#define VCARD0 \47typedef void (*vcard_func_t) (const char *file, VObject *vo, void *user_data);
36 "BEGIN:VCARD\n" \
37 "VERSION:3.0\n" \
38 "N:Klaus;Santa\n" \
39 "FN:\n" \
40 "TEL:+001122334455\n" \
41 "END:VCARD\n"
4248
43struct dummy_data {49struct dummy_data {
44 phonebook_cb cb;50 phonebook_cb cb;
45 gpointer user_data;51 void *user_data;
46 const struct apparam_field *apparams;52 const struct apparam_field *apparams;
47};53 char *folder;
54 int fd;
55};
56
57struct cache_query {
58 phonebook_entry_cb entry_cb;
59 phonebook_cache_ready_cb ready_cb;
60 void *user_data;
61 DIR *dp;
62};
63
64static char *root_folder = NULL;
65
66static void dummy_free(void *user_data)
67{
68 struct dummy_data *dummy = user_data;
69
70 if (dummy->fd >= 0)
71 close(dummy->fd);
72
73 g_free(dummy->folder);
74 g_free(dummy);
75}
76
77static void query_free(void *user_data)
78{
79 struct cache_query *query = user_data;
80
81 if (query->dp)
82 closedir(query->dp);
83
84 g_free(query);
85}
4886
49int phonebook_init(void)87int phonebook_init(void)
50{88{
89 /* FIXME: It should NOT be hard-coded */
90 root_folder = g_build_filename(getenv("HOME"), "phonebook", NULL);
91
51 return 0;92 return 0;
52}93}
5394
54void phonebook_exit(void)95void phonebook_exit(void)
55{96{
56}97 g_free(root_folder);
5798}
58static gboolean dummy_result(gpointer data)99
59{100static int handle_cmp(gconstpointer a, gconstpointer b)
60 struct dummy_data *dummy = data;101{
61102 const char *f1 = a;
62 dummy->cb(VCARD0, strlen(VCARD0), 1, 0, dummy->user_data);103 const char *f2 = b;
63104 unsigned int i1, i2;
64 return FALSE;105
65}106 if (sscanf(f1, "%u.vcf", &i1) != 1)
66107 return -1;
67int phonebook_set_folder(const gchar *current_folder,108
68 const gchar *new_folder, guint8 flags)109 if (sscanf(f2, "%u.vcf", &i2) != 1)
69{110 return -1;
70 return 0;111
71}112 return (i1 - i2);
72113}
73int phonebook_pull(const gchar *name, const struct apparam_field *params,114
74 phonebook_cb cb, gpointer user_data)115static int foreach_vcard(DIR *dp, vcard_func_t func, uint16_t offset,
75{116 uint16_t maxlistcount, void *user_data, uint16_t *count)
76 struct dummy_data *dummy;117{
77118 struct dirent *ep;
78 dummy = g_new0(struct dummy_data, 1);119 GSList *sorted = NULL, *l;
79 dummy->cb = cb;120 VObject *v;
80 dummy->user_data = user_data;121 FILE *fp;
81 dummy->apparams = params;122 int err, fd, folderfd;
82123 uint16_t n = 0;
83 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,124
84 dummy_result, dummy, g_free);125 folderfd = dirfd(dp);
126 if (folderfd < 0) {
127 err = errno;
128 error("dirfd(): %s(%d)", strerror(err), err);
129 return -err;
130 }
131
132 /*
133 * Sorting vcards by file name. versionsort is a GNU extension.
134 * The simple sorting function implemented on handle_cmp address
135 * vcards handle only(handle is always a number). This sort function
136 * doesn't address filename started by "0".
137 */
138 while ((ep = readdir(dp))) {
139 char *filename;
140
141 if (ep->d_name[0] == '.')
142 continue;
143
144 filename = g_filename_to_utf8(ep->d_name, -1, NULL, NULL, NULL);
145 if (filename == NULL) {
146 error("g_filename_to_utf8: invalid filename");
147 continue;
148 }
149
150 if (!g_str_has_suffix(filename, ".vcf")) {
151 g_free(filename);
152 continue;
153 }
154
155 sorted = g_slist_insert_sorted(sorted, filename, handle_cmp);
156 }
157
158 /*
159 * Filtering only the requested vCards attributes. Offset
160 * shall be based on the first entry of the phonebook.
161 */
162 for (l = g_slist_nth(sorted, offset);
163 l && n < maxlistcount; l = l->next) {
164 const char *filename = l->data;
165
166 fd = openat(folderfd, filename, O_RDONLY);
167 if (fd < 0) {
168 err = errno;
169 error("openat(%s): %s(%d)", filename, strerror(err), err);
170 continue;
171 }
172
173 fp = fdopen(fd, "r");
174 v = Parse_MIME_FromFile(fp);
175 if (v != NULL) {
176 func(filename, v, user_data);
177 deleteVObject(v);
178 n++;
179 }
180
181 close(fd);
182 }
183
184 g_slist_foreach(sorted, (GFunc) g_free, NULL);
185 g_slist_free(sorted);
186
187 if (count)
188 *count = n;
189
190 return 0;
191}
192
193static void entry_concat(const char *filename, VObject *v, void *user_data)
194{
195 GString *buffer = user_data;
196 char tmp[1024];
197 int len;
198
199 /*
200 * VObject API uses len for IN and OUT
201 * Written bytes is also returned in the len variable
202 */
203 len = sizeof(tmp);
204 memset(tmp, 0, len);
205
206 writeMemVObject(tmp, &len, v);
207
208 /* FIXME: only the requested fields must be added */
209 g_string_append_len(buffer, tmp, len);
210}
211
212static gboolean read_dir(void *user_data)
213{
214 struct dummy_data *dummy = user_data;
215 GString *buffer;
216 DIR *dp;
217 uint16_t count, max, offset;
218
219 buffer = g_string_new("");
220
221 dp = opendir(dummy->folder);
222 if (dp == NULL) {
223 int err = errno;
224 debug("opendir(): %s(%d)", strerror(err), err);
225 goto done;
226 }
227
228 /*
229 * For PullPhoneBook function, the decision of returning the size
230 * or contacts is made in the PBAP core. When MaxListCount is ZERO,
231 * PCE wants to know the size of a given folder, PSE shall ignore all
232 * other applicattion parameters that may be present in the request.
233 */
234 if (dummy->apparams->maxlistcount == 0) {
235 max = 0xffff;
236 offset = 0;
237 } else {
238 max = dummy->apparams->maxlistcount;
239 offset = dummy->apparams->liststartoffset;
240 }
241
242 foreach_vcard(dp, entry_concat, offset, max, buffer, &count);
243
244 closedir(dp);
245done:
246 /* FIXME: Missing vCards fields filtering */
247 dummy->cb(buffer->str, buffer->len, count, 0, dummy->user_data);
248
249 g_string_free(buffer, TRUE);
250
251 return FALSE;
252}
253
254static void entry_notify(const char *filename, VObject *v, void *user_data)
255{
256 struct cache_query *query = user_data;
257 VObject *property, *subproperty;
258 GString *name;
259 const char *tel;
260 long unsigned int handle;
261
262 property = isAPropertyOf(v, VCNameProp);
263 if (!property)
264 return;
265
266 if (sscanf(filename, "%lu.vcf", &handle) != 1)
267 return;
268
269 if (handle > UINT32_MAX)
270 return;
271
272 /* LastName; FirstName; MiddleName; Prefix; Suffix */
273
274 name = g_string_new("");
275 subproperty = isAPropertyOf(property, VCFamilyNameProp);
276 if (subproperty) {
277 g_string_append(name,
278 fakeCString(vObjectUStringZValue(subproperty)));
279 }
280
281 subproperty = isAPropertyOf(property, VCGivenNameProp);
282 if (subproperty)
283 g_string_append_printf(name, ";%s",
284 fakeCString(vObjectUStringZValue(subproperty)));
285
286 subproperty = isAPropertyOf(property, VCAdditionalNamesProp);
287 if (subproperty)
288 g_string_append_printf(name, ";%s",
289 fakeCString(vObjectUStringZValue(subproperty)));
290
291 subproperty = isAPropertyOf(property, VCNamePrefixesProp);
292 if (subproperty)
293 g_string_append_printf(name, ";%s",
294 fakeCString(vObjectUStringZValue(subproperty)));
295
296
297 subproperty = isAPropertyOf(property, VCNameSuffixesProp);
298 if (subproperty)
299 g_string_append_printf(name, ";%s",
300 fakeCString(vObjectUStringZValue(subproperty)));
301
302 property = isAPropertyOf(v, VCTelephoneProp);
303
304 tel = property ? fakeCString(vObjectUStringZValue(property)) : NULL;
305
306 query->entry_cb(filename, handle, name->str, NULL, tel,
307 query->user_data);
308 g_string_free(name, TRUE);
309}
310
311static gboolean create_cache(void *user_data)
312{
313 struct cache_query *query = user_data;
314
315 /*
316 * MaxListCount and ListStartOffset shall not be used
317 * when creating the cache. All entries shall be fetched.
318 * PBAP core is responsible for consider these application
319 * parameters before reply the entries.
320 */
321 foreach_vcard(query->dp, entry_notify, 0, 0xffff, query, NULL);
322
323 query->ready_cb(query->user_data);
324
325 return FALSE;
326}
327
328static gboolean read_entry(void *user_data)
329{
330 struct dummy_data *dummy = user_data;
331 char buffer[1024];
332 ssize_t count;
333
334 memset(buffer, 0, sizeof(buffer));
335 count = read(dummy->fd, buffer, sizeof(buffer));
336
337 if (count < 0) {
338 int err = errno;
339 error("read(): %s(%d)", strerror(err), err);
340 count = 0;
341 }
342
343 /* FIXME: Missing vCards fields filtering */
344
345 dummy->cb(buffer, count, 1, 0, dummy->user_data);
346
347 return FALSE;
348}
349
350static gboolean is_dir(const char *dir)
351{
352 struct stat st;
353
354 if (stat(dir, &st) < 0) {
355 int err = errno;
356 error("stat(%s): %s (%d)", dir, strerror(err), err);
357 return FALSE;
358 }
359
360 return S_ISDIR(st.st_mode);
361}
362
363char *phonebook_set_folder(const char *current_folder,
364 const char *new_folder, uint8_t flags, int *err)
365{
366 gboolean root, child;
367 char *tmp1, *tmp2, *base, *absolute, *relative = NULL;
368 int len, ret = 0;
369
370 root = (g_strcmp0("/", current_folder) == 0);
371 child = (new_folder && strlen(new_folder) != 0);
372
373 switch (flags) {
374 case 0x02:
375 /* Go back to root */
376 if (!child) {
377 relative = g_strdup("/");
378 goto done;
379 }
380
381 relative = g_build_filename(current_folder, new_folder, NULL);
382 break;
383 case 0x03:
384 /* Go up 1 level */
385 if (root) {
386 /* Already root */
387 ret = -EBADR;
388 goto done;
389 }
390
391 /*
392 * Removing one level of the current folder. Current folder
393 * contains AT LEAST one level since it is not at root folder.
394 * Use glib utility functions to handle invalid chars in the
395 * folder path properly.
396 */
397 tmp1 = g_path_get_basename(current_folder);
398 tmp2 = g_strrstr(current_folder, tmp1);
399 len = tmp2 - (current_folder + 1);
400
401 g_free(tmp1);
402
403 if (len == 0)
404 base = g_strdup("/");
405 else
406 base = g_strndup(current_folder, len);
407
408 /* Return: one level only */
409 if (!child) {
410 relative = base;
411 goto done;
412 }
413
414 relative = g_build_filename(base, new_folder, NULL);
415 g_free(base);
416
417 break;
418 default:
419 ret = -EBADR;
420 break;
421 }
422
423done:
424 if (!relative) {
425 if (err)
426 *err = ret;
427
428 return NULL;
429 }
430
431 absolute = g_build_filename(root_folder, relative, NULL);
432 if (!is_dir(absolute)) {
433 g_free(relative);
434 relative = NULL;
435 ret = -ENOENT;
436 }
437
438 g_free(absolute);
439
440 if (err)
441 *err = ret;
442
443 return relative;
444}
445
446int phonebook_pull(const char *name, const struct apparam_field *params,
447 phonebook_cb cb, void *user_data)
448{
449 struct dummy_data *dummy;
450 char *filename, *folder;
451
452 /*
453 * Main phonebook objects will be created dinamically based on the
454 * folder content. All vcards inside the given folder will be appended
455 * in the "virtual" main phonebook object.
456 */
457
458 filename = g_build_filename(root_folder, name, NULL);
459
460 if (!g_str_has_suffix(filename, ".vcf")) {
461 g_free(filename);
462 return -EBADR;
463 }
464
465 folder = g_strndup(filename, strlen(filename) - 4);
466 g_free(filename);
467 if (!is_dir(folder)) {
468 g_free(folder);
469 return -ENOENT;
470 }
471
472 dummy = g_new0(struct dummy_data, 1);
473 dummy->cb = cb;
474 dummy->user_data = user_data;
475 dummy->apparams = params;
476 dummy->folder = folder;
477 dummy->fd = -1;
478
479 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, read_dir, dummy, dummy_free);
480
481 return 0;
482}
483
484int phonebook_get_entry(const char *folder, const char *id,
485 const struct apparam_field *params,
486 phonebook_cb cb, void *user_data)
487{
488 struct dummy_data *dummy;
489 char *filename;
490 int fd;
491
492 filename = g_build_filename(root_folder, folder, id, NULL);
493
494 fd = open(filename, O_RDONLY);
495 if (fd < 0) {
496 int err = errno;
497 debug("open(): %s(%d)", strerror(err), err);
498 return -ENOENT;
499 }
500
501 dummy = g_new0(struct dummy_data, 1);
502 dummy->cb = cb;
503 dummy->user_data = user_data;
504 dummy->apparams = params;
505 dummy->fd = fd;
506
507 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, read_entry, dummy, dummy_free);
508
509 return 0;
510}
511
512int phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
513 phonebook_cache_ready_cb ready_cb, void *user_data)
514{
515 struct cache_query *query;
516 char *foldername;
517 DIR *dp;
518
519 foldername = g_build_filename(root_folder, name, NULL);
520 dp = opendir(foldername);
521 g_free(foldername);
522
523 if (dp == NULL) {
524 int err = errno;
525 debug("opendir(): %s(%d)", strerror(err), err);
526 return -ENOENT;
527 }
528
529 query = g_new0(struct cache_query, 1);
530 query->entry_cb = entry_cb;
531 query->ready_cb = ready_cb;
532 query->user_data = user_data;
533 query->dp = dp;
534
535 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, create_cache, query,
536 query_free);
85 return 0;537 return 0;
86}538}
87539
=== modified file 'plugins/phonebook-ebook.c'
--- plugins/phonebook-ebook.c 2010-04-27 04:17:15 +0000
+++ plugins/phonebook-ebook.c 2010-06-15 19:18:33 +0000
@@ -41,54 +41,250 @@
41#include "service.h"41#include "service.h"
42#include "phonebook.h"42#include "phonebook.h"
4343
44#define EOL_CHARS "\n"44#define QUERY_FN "(contains \"family_name\" \"%s\")"
45#define VL_VERSION "<?xml version=\"1.0\"?>" EOL_CHARS45#define QUERY_NAME "(contains \"given_name\" \"%s\")"
46#define VL_TYPE "<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">" EOL_CHARS
47#define VL_BODY_BEGIN "<vCard-listing version=\"1.0\">" EOL_CHARS
48#define VL_BODY_END "</vCard-listing>" EOL_CHARS
49#define VL_ELEMENT "<card handle = \"%d.vcf\" name = \"%s\"/>" EOL_CHARS
50
51#define QUERY_FAMILY_NAME "(contains \"family_name\" \"%s\")"
52#define QUERY_GIVEN_NAME "(contains \"given_name\" \"%s\")"
53#define QUERY_PHONE "(contains \"phone\" \"%s\")"46#define QUERY_PHONE "(contains \"phone\" \"%s\")"
5447
55struct query_data {48struct contacts_query {
56 const struct apparam_field *params;49 const struct apparam_field *params;
57 phonebook_cb cb;50 phonebook_cb cb;
58 gpointer user_data;51 void *user_data;
52};
53
54struct cache_query {
55 phonebook_entry_cb entry_cb;
56 phonebook_cache_ready_cb ready_cb;
57 void *user_data;
59};58};
6059
61static EBook *ebook = NULL;60static EBook *ebook = NULL;
6261
63static void ebookpull_cb(EBook *book, EBookStatus status, GList *contacts,62static char *attribute_mask[] = {
64 gpointer user_data)63/* 0 */ "VERSION",
65{64 "FN",
66 struct query_data *data = user_data;65 "N",
66 "PHOTO",
67 "BDAY",
68 "ADR",
69 "LABEL",
70 "TEL",
71/* 8 */ "EMAIL",
72 "MAILER",
73 "TZ",
74 "GEO",
75 "TITLE",
76 "ROLE",
77 "LOGO",
78 "AGENT",
79/* 16 */ "ORG",
80 "NOTE",
81 "REV",
82 "SOUND",
83 "URL",
84 "UID",
85 "KEY",
86 "NICKNAME",
87/* 24 */ "CATEGORIES",
88 "PROID",
89 "CLASS",
90 "SORT-STRING",
91/* 28 */ "X-IRMC-CALL-DATETIME",
92 NULL
93
94};
95
96static char *evcard_to_string(EVCard *evcard, unsigned int format,
97 uint64_t filter)
98{
99 EVCard *evcard2;
100 char *vcard;
101 unsigned int i;
102
103 if (!filter)
104 return e_vcard_to_string(evcard, format);
105
106 /*
107 * Mandatory attributes for vCard 2.1 are VERSION ,N and TEL.
108 * Mandatory attributes for vCard 3.0 are VERSION, N, FN and TEL
109 */
110 filter = format == EVC_FORMAT_VCARD_30 ? filter | 0x85: filter | 0x87;
111
112 evcard2 = e_vcard_new();
113 for (i = 0; i < 29; i++) {
114 EVCardAttribute *attrib;
115
116 if (!(filter & (1 << i)))
117 continue;
118
119 attrib = e_vcard_get_attribute(evcard, attribute_mask[i]);
120 if (!attrib)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches