summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2013-09-17 11:30:01 +0200
committerGravatar Nikias Bassen2013-09-17 11:30:01 +0200
commitf4758e8b15cd30fe3f7f18de42e2ea20bc5696f0 (patch)
tree671e85e639b689b0b888a0f51c7dd5e15d408930
parent10939f3ad5755d1117f20df2b97c0cbbd83bbcbe (diff)
downloadusbmuxd-f4758e8b15cd30fe3f7f18de42e2ea20bc5696f0.tar.gz
usbmuxd-f4758e8b15cd30fe3f7f18de42e2ea20bc5696f0.tar.bz2
remove libusbmuxd sources and adapt source tree to use autotools
libusbmuxd has been split off and is now managed in a separate repository. By the time of this commit, the repository is: git clone http://git.sukimashita.com/libusbmuxd.git
-rw-r--r--.gitignore38
-rw-r--r--CMakeLists.txt83
-rw-r--r--COPYING.LGPLv2.1502
-rw-r--r--Makefile.am3
-rw-r--r--Modules/CheckConstantExists.cmake38
-rw-r--r--Modules/FindInotify.cmake11
-rw-r--r--Modules/FindPLIST.cmake31
-rw-r--r--Modules/FindUSB.cmake40
-rw-r--r--Modules/LibFindMacros.cmake99
-rw-r--r--Modules/VersionTag.cmake13
-rw-r--r--Modules/cmake_uninstall.cmake.in21
-rwxr-xr-xModules/describe.sh17
-rw-r--r--README12
-rw-r--r--README.devel50
-rwxr-xr-xautogen.sh15
-rw-r--r--configure.ac96
-rw-r--r--daemon/CMakeLists.txt23
-rw-r--r--libusbmuxd.pc.in11
-rw-r--r--libusbmuxd/CMakeLists.txt45
-rw-r--r--libusbmuxd/libusbmuxd.c975
-rw-r--r--libusbmuxd/sock_stuff.c375
-rw-r--r--libusbmuxd/sock_stuff.h65
-rw-r--r--libusbmuxd/usbmuxd-proto.h97
-rw-r--r--libusbmuxd/usbmuxd.h191
-rw-r--r--m4/as-compiler-flag.m462
-rw-r--r--python-client/.gitignore3
-rw-r--r--python-client/tcprelay.py148
-rw-r--r--python-client/usbmux.py246
-rw-r--r--src/Makefile.am14
-rw-r--r--src/client.c (renamed from daemon/client.c)0
-rw-r--r--src/client.h (renamed from daemon/client.h)0
-rw-r--r--src/device.c (renamed from daemon/device.c)0
-rw-r--r--src/device.h (renamed from daemon/device.h)0
-rw-r--r--src/log.c (renamed from daemon/log.c)0
-rw-r--r--src/log.h (renamed from daemon/log.h)0
-rw-r--r--src/main.c (renamed from daemon/main.c)2
-rw-r--r--src/usb-linux.c (renamed from daemon/usb-linux.c)0
-rw-r--r--src/usb.h (renamed from daemon/usb.h)0
-rw-r--r--src/utils.c (renamed from common/utils.c)10
-rw-r--r--src/utils.h (renamed from common/utils.h)2
-rw-r--r--stuff/README25
-rw-r--r--stuff/com.openssh.sftp.plist41
-rw-r--r--tools/CMakeLists.txt11
-rw-r--r--tools/iproxy.c281
-rw-r--r--udev/85-usbmuxd.rules.in4
-rw-r--r--udev/CMakeLists.txt2
46 files changed, 232 insertions, 3470 deletions
diff --git a/.gitignore b/.gitignore
index 0784410..9a9e6e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,37 @@
1# git-ls-files --others --exclude-from=.git/info/exclude
2# Lines that start with '#' are comments.
3# For a project mostly in C, the following would be a good set of
4# exclude patterns (uncomment them if you want to use them):
5*.[oa]
1*~ 6*~
2build 7*.po
3 8*.lo
9*.la
10autom4te.cache/*
11*.in
12*/.deps/*
13m4/*
14swig/*
15*.swp
16*.patch
17aclocal.m4
18config.h
19config.log
20config.sub
21config.guess
22config.status
23configure
24depcomp
25install-sh
26compile
27main
28ltmain.sh
29missing
30mkinstalldirs
31libtool
32*Makefile
33py-compile
34stamp-h1
35src/.libs
36src/usbmuxd
37udev/85-usbmuxd.rules
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 7a46282..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,83 +0,0 @@
1PROJECT(usbmuxd)
2
3cmake_minimum_required(VERSION 2.6)
4
5set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/Modules/")
6
7include(VersionTag)
8
9set(USBMUXD_VERSION "${VERSION_TAG}")
10set(LIBUSBMUXD_VERSION "${VERSION_TAG}")
11set(LIBUSBMUXD_SOVERSION "2")
12
13message("-- Configuring usbmuxd v${VERSION_TAG}")
14
15if(NOT DEFINED LIB_SUFFIX)
16 if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
17 set(LIB_SUFFIX "64" CACHE STRING "Define suffix of library directory name (32/64)" )
18 else()
19 set(LIB_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
20 endif()
21endif()
22
23# let CFLAGS env override this
24if(CMAKE_C_FLAGS STREQUAL "")
25 set(CMAKE_C_FLAGS "-O2")
26endif()
27
28option(WANT_PLIST "Build with protocol version 1 support using libplist" ON)
29
30set(OPT_INCLUDES "")
31set(OPT_LIBS "")
32if(WANT_PLIST)
33 find_package(PLIST)
34 if(PLIST_FOUND)
35 set(HAVE_PLIST ON)
36 set(OPT_INCLUDES ${OPT_INCLUDES} ${PLIST_INCLUDE_DIRS})
37 set(OPT_LIBS ${OPT_LIBS} ${PLIST_LIBRARIES})
38 else()
39 message("* NOTE: libplist was not found!")
40 message("* libusbmuxd/usbmuxd will be build WITHOUT support for version 1")
41 message("* of the usbmux protocol (plist based).")
42 endif()
43endif()
44
45option(WITH_USBMUXD "Build usbmux daemon (usbmuxd)" ON)
46if(WIN32 AND WITH_USBMUXD)
47 message("** NOTE: usbmuxd cannot be built on WIN32 due to missing libusb-1.0 support!")
48 message(" If you need your own usbmuxd you have to use usbmuxd-legacy which works")
49 message(" with libusb-0.1; otherwise just use the one that ships with iTunes.")
50 message(" Building of usbmuxd has been disabled.")
51 set(WITH_USBMUXD OFF)
52endif()
53if(WITH_USBMUXD)
54 message("-- Will build usbmuxd: YES")
55else()
56 message("-- Will build usbmuxd: NO")
57 message("** NOTE: will NOT build usbmuxd **")
58 if(WIN32 OR APPLE)
59 message("** Make sure iTunes is installed, otherwise this software will not work! **")
60 else()
61 message("** You'll need a working usbmuxd implementation for this software to work! **")
62 endif()
63endif()
64
65add_definitions(-Wall)
66
67add_subdirectory (libusbmuxd)
68if (WITH_USBMUXD)
69 add_subdirectory (daemon)
70 if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
71 add_subdirectory (udev)
72 endif()
73endif()
74add_subdirectory (tools)
75
76# pkg-config
77configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libusbmuxd.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libusbmuxd.pc")
78# install pkg-config file
79install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libusbmuxd.pc" DESTINATION lib${LIB_SUFFIX}/pkgconfig/)
80
81# add uninstall target
82configure_file("${CMAKE_SOURCE_DIR}/Modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
83add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
diff --git a/COPYING.LGPLv2.1 b/COPYING.LGPLv2.1
deleted file mode 100644
index 732811e..0000000
--- a/COPYING.LGPLv2.1
+++ /dev/null
@@ -1,502 +0,0 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
459
460 How to Apply These Terms to Your New Libraries
461
462 If you develop a new library, and you want it to be of the greatest
463possible use to the public, we recommend making it free software that
464everyone can redistribute and change. You can do so by permitting
465redistribution under these terms (or, alternatively, under the terms of the
466ordinary General Public License).
467
468 To apply these terms, attach the following notices to the library. It is
469safest to attach them to the start of each source file to most effectively
470convey the exclusion of warranty; and each file should have at least the
471"copyright" line and a pointer to where the full notice is found.
472
473 <one line to give the library's name and a brief idea of what it does.>
474 Copyright (C) <year> <name of author>
475
476 This library is free software; you can redistribute it and/or
477 modify it under the terms of the GNU Lesser General Public
478 License as published by the Free Software Foundation; either
479 version 2.1 of the License, or (at your option) any later version.
480
481 This library is distributed in the hope that it will be useful,
482 but WITHOUT ANY WARRANTY; without even the implied warranty of
483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 Lesser General Public License for more details.
485
486 You should have received a copy of the GNU Lesser General Public
487 License along with this library; if not, write to the Free Software
488 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
489
490Also add information on how to contact you by electronic and paper mail.
491
492You should also get your employer (if you work as a programmer) or your
493school, if any, to sign a "copyright disclaimer" for the library, if
494necessary. Here is a sample; alter the names:
495
496 Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499 <signature of Ty Coon>, 1 April 1990
500 Ty Coon, President of Vice
501
502That's all there is to it!
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..2cb1ca0
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,3 @@
1AUTOMAKE_OPTIONS = foreign
2ACLOCAL_AMFLAGS = -I m4
3SUBDIRS = src
diff --git a/Modules/CheckConstantExists.cmake b/Modules/CheckConstantExists.cmake
deleted file mode 100644
index 3d6d97e..0000000
--- a/Modules/CheckConstantExists.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
1# - Check if the given constant exists (as an enum, define, or whatever)
2# CHECK_CONSTANT_EXISTS (CONSTANT HEADER VARIABLE)
3#
4# CONSTANT - the name of the constant you are interested in
5# HEADER - the header(s) where the prototype should be declared
6# VARIABLE - variable to store the result
7#
8# The following variables may be set before calling this macro to
9# modify the way the check is run:
10#
11# CMAKE_REQUIRED_FLAGS = string of compile command line flags
12# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
13# CMAKE_REQUIRED_INCLUDES = list of include directories
14#
15# Example: CHECK_CONSTANT_EXISTS(O_NOFOLLOW fcntl.h HAVE_O_NOFOLLOW)
16
17
18INCLUDE(CheckCSourceCompiles)
19
20MACRO (CHECK_CONSTANT_EXISTS _CONSTANT _HEADER _RESULT)
21 SET(_INCLUDE_FILES)
22 FOREACH (it ${_HEADER})
23 SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
24 ENDFOREACH (it)
25
26 SET(_CHECK_CONSTANT_SOURCE_CODE "
27${_INCLUDE_FILES}
28void cmakeRequireConstant(int dummy,...){(void)dummy;}
29int main()
30{
31 cmakeRequireConstant(0,${_CONSTANT});
32 return 0;
33}
34")
35 CHECK_C_SOURCE_COMPILES("${_CHECK_CONSTANT_SOURCE_CODE}" ${_RESULT})
36
37ENDMACRO (CHECK_CONSTANT_EXISTS)
38
diff --git a/Modules/FindInotify.cmake b/Modules/FindInotify.cmake
deleted file mode 100644
index 90496d4..0000000
--- a/Modules/FindInotify.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
1set(INOTIFY_H "NOTFOUND")
2find_file(INOTIFY_H
3 "sys/inotify.h"
4 PATHS ENV INCLUDE
5)
6
7if (INOTIFY_H)
8 set(INOTIFY_FOUND TRUE)
9else()
10 set(INOTIFY_FOUND FALSE)
11endif()
diff --git a/Modules/FindPLIST.cmake b/Modules/FindPLIST.cmake
deleted file mode 100644
index d51aa74..0000000
--- a/Modules/FindPLIST.cmake
+++ /dev/null
@@ -1,31 +0,0 @@
1# - Try to find libplist
2# Once done, this will define
3#
4# PLIST_FOUND - system has libplist
5# PLIST_INCLUDE_DIRS - the libplist include directories
6# PLIST_LIBRARIES - link these to use libplist
7
8include(LibFindMacros)
9
10# Dependencies
11
12# Use pkg-config to get hints about paths
13libfind_pkg_check_modules(PLIST_PKGCONF libplist >= 0.15)
14
15# Include dir
16find_path(PLIST_INCLUDE_DIR
17 NAMES plist/plist.h
18 PATHS ${PLIST_PKGCONF_INCLUDE_DIRS}
19)
20
21# Finally the library itself
22find_library(PLIST_LIBRARY
23 NAMES plist
24 PATHS ${PLIST_PKGCONF_LIBRARY_DIRS}
25)
26
27# Set the include dir variables and the libraries and let libfind_process do the rest.
28# NOTE: Singular variables for this library, plural for libraries that this lib depends on.
29set(PLIST_PROCESS_INCLUDES PLIST_INCLUDE_DIR)
30set(PLIST_PROCESS_LIBS PLIST_LIBRARY)
31libfind_process(PLIST)
diff --git a/Modules/FindUSB.cmake b/Modules/FindUSB.cmake
deleted file mode 100644
index 486864f..0000000
--- a/Modules/FindUSB.cmake
+++ /dev/null
@@ -1,40 +0,0 @@
1# - Try to find libusb-1.0
2# Once done, this will define
3#
4# USB_FOUND - system has libusb-1.0
5# USB_INCLUDE_DIRS - the libusb-1.0 include directories
6# USB_LIBRARIES - link these to use libusb-1.0
7
8include(LibFindMacros)
9
10# Dependencies
11
12# pkg-config + libusb fails on FreeBSD, though libusb is in base
13if(NOT(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD"))
14 # Use pkg-config to get hints about paths
15 libfind_pkg_check_modules(USB_PKGCONF libusb-1.0>=1.0.3)
16 # We want to look for libusb-1.0
17 set(USB_LIBRARY_NAME usb-1.0)
18else()
19 set(USB_PKGCONF_INCLUDE_DIRS /usr/include)
20 set(USB_PKGCONF_LIBRARY_DIRS /usr/lib)
21 set(USB_LIBRARY_NAME usb)
22endif()
23
24# Include dir
25find_path(USB_INCLUDE_DIR
26 NAMES libusb.h
27 PATHS ${USB_PKGCONF_INCLUDE_DIRS}
28)
29
30# Finally the library itself
31find_library(USB_LIBRARY
32 NAMES ${USB_LIBRARY_NAME}
33 PATHS ${USB_PKGCONF_LIBRARY_DIRS}
34)
35
36# Set the include dir variables and the libraries and let libfind_process do the rest.
37# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
38set(USB_PROCESS_INCLUDES USB_INCLUDE_DIR)
39set(USB_PROCESS_LIBS USB_LIBRARY)
40libfind_process(USB)
diff --git a/Modules/LibFindMacros.cmake b/Modules/LibFindMacros.cmake
deleted file mode 100644
index 795d6b7..0000000
--- a/Modules/LibFindMacros.cmake
+++ /dev/null
@@ -1,99 +0,0 @@
1# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
2# used for the current package. For this to work, the first parameter must be the
3# prefix of the current package, then the prefix of the new package etc, which are
4# passed to find_package.
5macro (libfind_package PREFIX)
6 set (LIBFIND_PACKAGE_ARGS ${ARGN})
7 if (${PREFIX}_FIND_QUIETLY)
8 set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
9 endif (${PREFIX}_FIND_QUIETLY)
10 if (${PREFIX}_FIND_REQUIRED)
11 set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
12 endif (${PREFIX}_FIND_REQUIRED)
13 find_package(${LIBFIND_PACKAGE_ARGS})
14endmacro (libfind_package)
15
16# Damn CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
17# where they added pkg_check_modules. Consequently I need to support both in my scripts
18# to avoid those deprecated warnings. Here's a helper that does just that.
19# Works identically to pkg_check_modules, except that no checks are needed prior to use.
20macro (libfind_pkg_check_modules PREFIX PKGNAME)
21 if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
22 include(UsePkgConfig)
23 pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
24 else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
25 find_package(PkgConfig)
26 if (PKG_CONFIG_FOUND)
27 pkg_check_modules(${PREFIX} ${PKGNAME})
28 endif (PKG_CONFIG_FOUND)
29 endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
30endmacro (libfind_pkg_check_modules)
31
32# Do the final processing once the paths have been detected.
33# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
34# all the variables, each of which contain one include directory.
35# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
36# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
37# Also handles errors in case library detection was required, etc.
38macro (libfind_process PREFIX)
39 # Skip processing if already processed during this run
40 if (NOT ${PREFIX}_FOUND)
41 # Start with the assumption that the library was found
42 set (${PREFIX}_FOUND TRUE)
43
44 # Process all includes and set _FOUND to false if any are missing
45 foreach (i ${${PREFIX}_PROCESS_INCLUDES})
46 if (${i})
47 set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
48 mark_as_advanced(${i})
49 else (${i})
50 set (${PREFIX}_FOUND FALSE)
51 endif (${i})
52 endforeach (i)
53
54 # Process all libraries and set _FOUND to false if any are missing
55 foreach (i ${${PREFIX}_PROCESS_LIBS})
56 if (${i})
57 set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
58 mark_as_advanced(${i})
59 else (${i})
60 set (${PREFIX}_FOUND FALSE)
61 endif (${i})
62 endforeach (i)
63
64 # Print message and/or exit on fatal error
65 if (${PREFIX}_FOUND)
66 if (NOT ${PREFIX}_FIND_QUIETLY)
67 message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
68 endif (NOT ${PREFIX}_FIND_QUIETLY)
69 else (${PREFIX}_FOUND)
70 if (${PREFIX}_FIND_REQUIRED)
71 foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
72 message("${i}=${${i}}")
73 endforeach (i)
74 message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
75 endif (${PREFIX}_FIND_REQUIRED)
76 endif (${PREFIX}_FOUND)
77 endif (NOT ${PREFIX}_FOUND)
78endmacro (libfind_process)
79
80macro(libfind_library PREFIX basename)
81 set(TMP "")
82 if(MSVC80)
83 set(TMP -vc80)
84 endif(MSVC80)
85 if(MSVC90)
86 set(TMP -vc90)
87 endif(MSVC90)
88 set(${PREFIX}_LIBNAMES ${basename}${TMP})
89 if(${ARGC} GREATER 2)
90 set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
91 string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
92 set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
93 endif(${ARGC} GREATER 2)
94 find_library(${PREFIX}_LIBRARY
95 NAMES ${${PREFIX}_LIBNAMES}
96 PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
97 )
98endmacro(libfind_library)
99
diff --git a/Modules/VersionTag.cmake b/Modules/VersionTag.cmake
deleted file mode 100644
index 682ab3e..0000000
--- a/Modules/VersionTag.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
1execute_process(
2 COMMAND "sh" "${CMAKE_SOURCE_DIR}/Modules/describe.sh"
3 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
4 OUTPUT_VARIABLE DESCRIBE
5 OUTPUT_STRIP_TRAILING_WHITESPACE
6)
7
8if(DESCRIBE STREQUAL "")
9 set (VERSION_TAG "UNKNOWN")
10else()
11 string(REGEX REPLACE "^v" "" VERSION_TAG "${DESCRIBE}")
12endif()
13
diff --git a/Modules/cmake_uninstall.cmake.in b/Modules/cmake_uninstall.cmake.in
deleted file mode 100644
index 4bfb0bf..0000000
--- a/Modules/cmake_uninstall.cmake.in
+++ /dev/null
@@ -1,21 +0,0 @@
1IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
2 MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
3ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
4
5FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
6STRING(REGEX REPLACE "\n" ";" files "${files}")
7FOREACH(file ${files})
8 MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
9 IF(EXISTS "$ENV{DESTDIR}${file}")
10 EXEC_PROGRAM(
11 "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
12 OUTPUT_VARIABLE rm_out
13 RETURN_VALUE rm_retval
14 )
15 IF(NOT "${rm_retval}" STREQUAL 0)
16 MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
17 ENDIF(NOT "${rm_retval}" STREQUAL 0)
18 ELSE(EXISTS "$ENV{DESTDIR}${file}")
19 MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
20 ENDIF(EXISTS "$ENV{DESTDIR}${file}")
21ENDFOREACH(file)
diff --git a/Modules/describe.sh b/Modules/describe.sh
deleted file mode 100755
index 6425ed5..0000000
--- a/Modules/describe.sh
+++ /dev/null
@@ -1,17 +0,0 @@
1#!/bin/bash
2
3# Check for git and a git repo.
4if head=`git rev-parse --verify HEAD 2>/dev/null`; then
5 /bin/echo -n `git describe`
6
7 # Are there uncommitted changes?
8 git update-index --refresh --unmerged > /dev/null
9 git diff-index --quiet HEAD || /bin/echo -n -dirty
10else
11# Check for version tag
12 if [ -e version.tag ]; then
13 /bin/echo -n `cat version.tag`
14 fi
15fi
16
17echo
diff --git a/README b/README
index bad7531..2f09d21 100644
--- a/README
+++ b/README
@@ -17,21 +17,11 @@ notification and backup services running on the device).
17The higher-level layers are handled by libimobiledevice. 'ifuse' is then able 17The higher-level layers are handled by libimobiledevice. 'ifuse' is then able
18to sit on top of this and mount your device's AFC filesystem share. 18to sit on top of this and mount your device's AFC filesystem share.
19 19
20There is also a Python implementation of the client library in the python-client
21library, and an example tcprelay.py which performs a similar function to iproxy.
22This implementation supports OSX and Windows and the new iTunes plist-based
23usbmuxd protocol, so it is portable and will run on those operating systems with
24no modification, using Apple's native usbmuxd. This is useful if you need to
25tunnel to your device from another OS in a pinch. Run python tcpclient.py --help
26for usage information.
27
28License 20License
29======= 21=======
30 22
31The contents of this package are licensed under the GNU General Public License, 23The contents of this package are licensed under the GNU General Public License,
32versions 2 or 3 (see COPYING.GPLv2 and COPYING.GPLv3), except for libuxbmuxd 24versions 2 or 3 (see COPYING.GPLv2 and COPYING.GPLv3). If a more permissive
33which is licensed under the GNU Lesser General Public License, version 2.1 or,
34at your option, any later version (see COPYING.LGPLv2.1). If a more permissive
35license is specified at the top of a source file, it takes precedence over this. 25license is specified at the top of a source file, it takes precedence over this.
36 26
37Legal 27Legal
diff --git a/README.devel b/README.devel
deleted file mode 100644
index 727e095..0000000
--- a/README.devel
+++ /dev/null
@@ -1,50 +0,0 @@
1Background
2==========
3
4'libusbmuxd' makes it really simple to talk to a running 'usbmuxd' and
5hides all the details for you. There are two function calls:
6
7usbmuxd_scan()
8--------------
9
10This returns a list of all available iPhone-like devices that are
11available for talking to. The returned array contains the USB
12product_id, hex formatted serial_number of any iPhones/iTouches and a
13non-descript 'handle' for all those devices that are within range (as
14of March 2009, that means a device directly plugged into the
15computer's USB port).
16
17Once you have found the device you want to communicate with, take its
18'handle' and pass this to usbmuxd_connect().
19
20usbmuxd_connect()
21-----------------
22
23This takes a handle, a destination port number and tries to setup
24a proxy a connection. It returns a file-descriptor which you should
25be able to read(), write() and select() on like any other active network
26socket connection.
27
28
29Technical details
30=================
31
32When usbmuxd is running (normally started, or stopped as a result of
33'udev' auto-insertion messages), it provides a socket interface in
34'/var/run/usbmuxd' that is designed to be compatible with the socket
35interface that is provided on MacOSX.
36
37The structures for communicating over this device are documented
38in the 'usbmuxd-proto.h', but you shouldn't need to view them
39directly if you are using the libusbmuxd.so library for easy access.
40
41
42Example
43=======
44
45#include <usbmuxd.h>
46
47...
48
49gcc -o leetphone leetphone.c -lusbmuxd
50
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..3292973
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,15 @@
1#!/bin/sh
2gprefix=`which glibtoolize 2>&1 >/dev/null`
3if [ $? -eq 0 ]; then
4 glibtoolize --force
5else
6 libtoolize --force
7fi
8aclocal -I m4
9autoheader
10automake --add-missing
11autoconf
12
13if [ -z "$NOCONFIGURE" ]; then
14 ./configure "$@"
15fi
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..a874692
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,96 @@
1# -*- Autoconf -*-
2# Process this file with autoconf to produce a configure script.
3
4AC_PREREQ(2.61)
5AC_INIT(usbmuxd, 1.0.8, nospam@nowhere.com)
6AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
7m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
8AC_CONFIG_SRCDIR([src/])
9AC_CONFIG_HEADERS([config.h])
10AC_CONFIG_MACRO_DIR([m4])
11
12# Checks for programs.
13AC_PROG_CC
14AC_PROG_CXX
15AM_PROG_CC_C_O
16AC_PROG_LIBTOOL
17
18# Checks for libraries.
19PKG_CHECK_MODULES(libusb, libusb-1.0 >= 1.0.3)
20PKG_CHECK_MODULES(libplist, libplist >= 1.9, have_plist=yes, have_plist=no)
21
22AC_ARG_WITH([protov1],
23 [AS_HELP_STRING([--without-protov1],
24 [do not build with protocol v1 support (default is yes)])],
25 [with_protov1=no],
26 [with_protov1=yes])
27
28if test "x$have_plist" = "xyes"; then
29 if test "x$with_protov1" != "xyes"; then
30 have_plist=no
31 echo "*** Note: Protocol V1 support has been disabled ***"
32 else
33 AC_DEFINE(HAVE_PLIST, 1, [Define if you have libplist support])
34 AC_SUBST(libplist_CFLAGS)
35 AC_SUBST(libplist_LIBS)
36 fi
37else
38 if test "x$with_protov1" == "xyes"; then
39 AC_MSG_ERROR([protocol V1 support requested but libplist could not be found])
40 fi
41fi
42
43# Checks for header files.
44AC_HEADER_STDC
45AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
46
47# Checks for typedefs, structures, and compiler characteristics.
48AC_C_CONST
49AC_TYPE_SIZE_T
50AC_TYPE_SSIZE_T
51AC_TYPE_UINT16_T
52AC_TYPE_UINT32_T
53AC_TYPE_UINT8_T
54
55# Checks for library functions.
56AC_FUNC_MALLOC
57AC_FUNC_REALLOC
58AC_CHECK_FUNCS([strcasecmp strdup strerror strndup])
59
60# Check for operating system
61AC_MSG_CHECKING([whether to enable WIN32 build settings])
62case ${host_os} in
63 *mingw32*|*cygwin*)
64 win32=true
65 AC_MSG_RESULT([yes])
66 AC_CHECK_TOOL([WINDRES], [windres], AC_MSG_ERROR([windres not found]))
67 AC_SUBST(WINDRES)
68 ;;
69 *)
70 win32=false
71 AC_MSG_RESULT([no])
72 ;;
73esac
74AM_CONDITIONAL(WIN32, test x$win32 = xtrue)
75
76AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter")
77AC_SUBST(GLOBAL_CFLAGS)
78
79m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
80
81AC_OUTPUT([
82Makefile
83src/Makefile
84udev/85-usbmuxd.rules
85])
86
87echo "
88Configuration for $PACKAGE $VERSION:
89-------------------------------------------
90
91 Install prefix: .........: $prefix
92 Protocol v1 support: ....: $have_plist
93
94 Now type 'make' to build $PACKAGE $VERSION,
95 and then 'make install' for installation.
96"
diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt
deleted file mode 100644
index c323f7b..0000000
--- a/daemon/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
1find_package(USB REQUIRED)
2include_directories(${USB_INCLUDE_DIRS})
3include_directories(${OPT_INCLUDES})
4set(LIBS ${LIBS} ${USB_LIBRARIES} ${OPT_LIBS})
5if(HAVE_PLIST)
6 add_definitions("-DHAVE_PLIST")
7 message("-- usbmuxd will be built with protocol version 1 support")
8endif()
9include_directories (${CMAKE_SOURCE_DIR}/common)
10include_directories (${CMAKE_SOURCE_DIR}/daemon)
11include_directories (${CMAKE_SOURCE_DIR}/libusbmuxd)
12
13add_definitions(-DUSBMUXD_DAEMON -DUSBMUXD_VERSION="${USBMUXD_VERSION}")
14add_executable(usbmuxd main.c usb-linux.c log.c ${CMAKE_SOURCE_DIR}/common/utils.c device.c client.c)
15target_link_libraries(usbmuxd ${LIBS})
16
17install(TARGETS usbmuxd RUNTIME DESTINATION sbin)
18
19message("
20* REMINDER
21* Remember to add a user named 'usbmux' with USB access permissions
22* for the udev hotplugging feature to work out of the box.
23")
diff --git a/libusbmuxd.pc.in b/libusbmuxd.pc.in
deleted file mode 100644
index 1ecd8ed..0000000
--- a/libusbmuxd.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
1prefix=${CMAKE_INSTALL_PREFIX}
2exec_prefix=${CMAKE_INSTALL_PREFIX}
3libdir=${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}
4includedir=${CMAKE_INSTALL_PREFIX}/include
5
6Name: libusbmuxd
7Description: A library to communicate with the usbmux daemon
8Version: ${USBMUXD_VERSION}
9Libs: -L${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX} -lusbmuxd
10Cflags: -I${CMAKE_INSTALL_PREFIX}/include
11
diff --git a/libusbmuxd/CMakeLists.txt b/libusbmuxd/CMakeLists.txt
deleted file mode 100644
index 737eb02..0000000
--- a/libusbmuxd/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
1include_directories (${CMAKE_SOURCE_DIR}/common)
2find_package(Threads)
3
4option(WANT_INOTIFY "Build with inotify support" ON)
5if (WANT_INOTIFY)
6find_package(Inotify)
7if (INOTIFY_FOUND)
8 add_definitions("-DHAVE_INOTIFY")
9 message("-- libusbmuxd will be built with inotify support")
10endif()
11endif(WANT_INOTIFY)
12
13add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c)
14find_library (PTHREAD pthread)
15
16if (HAVE_PLIST)
17 add_definitions("-DHAVE_PLIST")
18 message("-- libusbmuxd will be built with protocol version 1 support")
19endif()
20if(WIN32)
21 set(OPT_LIBS ${OPT_LIBS} ws2_32)
22endif()
23include_directories(${OPT_INCLUDES})
24target_link_libraries (libusbmuxd ${CMAKE_THREAD_LIBS_INIT} ${OPT_LIBS})
25
26# 'lib' is a UNIXism, the proper CMake target is usbmuxd
27# But we can't use that due to the conflict with the usbmuxd daemon,
28# so instead change the library output base name to usbmuxd here
29set_target_properties(libusbmuxd PROPERTIES OUTPUT_NAME usbmuxd)
30set_target_properties(libusbmuxd PROPERTIES VERSION ${LIBUSBMUXD_VERSION})
31set_target_properties(libusbmuxd PROPERTIES SOVERSION ${LIBUSBMUXD_SOVERSION})
32
33if(APPLE)
34 set_target_properties(libusbmuxd PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
35endif()
36if(WIN32)
37 set_target_properties(libusbmuxd PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib")
38endif()
39
40install(TARGETS libusbmuxd
41 RUNTIME DESTINATION bin
42 ARCHIVE DESTINATION lib${LIB_SUFFIX}
43 LIBRARY DESTINATION lib${LIB_SUFFIX}
44)
45install(FILES usbmuxd.h usbmuxd-proto.h DESTINATION include)
diff --git a/libusbmuxd/libusbmuxd.c b/libusbmuxd/libusbmuxd.c
deleted file mode 100644
index 20ac8ab..0000000
--- a/libusbmuxd/libusbmuxd.c
+++ /dev/null
@@ -1,975 +0,0 @@
1/*
2 libusbmuxd - client library to talk to usbmuxd
3
4Copyright (C) 2009-2010 Nikias Bassen <nikias@gmx.li>
5Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
6Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com>
7
8This library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as
10published by the Free Software Foundation, either version 2.1 of the
11License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
24#include <stdint.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <stdio.h>
28#include <string.h>
29#ifdef WIN32
30#include <windows.h>
31#include <winsock2.h>
32#define sleep(x) Sleep(x*1000)
33#ifndef EPROTO
34#define EPROTO 134
35#endif
36#ifndef EBADMSG
37#define EBADMSG 104
38#endif
39#else
40#include <sys/socket.h>
41#include <arpa/inet.h>
42#include <pthread.h>
43#endif
44
45#ifdef HAVE_INOTIFY
46#include <sys/inotify.h>
47#define EVENT_SIZE (sizeof (struct inotify_event))
48#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
49#define USBMUXD_DIRNAME "/var/run"
50#define USBMUXD_SOCKET_NAME "usbmuxd"
51#endif /* HAVE_INOTIFY */
52
53#include <unistd.h>
54#include <signal.h>
55
56#ifdef HAVE_PLIST
57#include <plist/plist.h>
58#define PLIST_BUNDLE_ID "com.marcansoft.usbmuxd"
59#define PLIST_CLIENT_VERSION_STRING "usbmuxd built for freedom"
60#define PLIST_PROGNAME "libusbmuxd"
61#endif
62
63// usbmuxd public interface
64#include "usbmuxd.h"
65// usbmuxd protocol
66#include "usbmuxd-proto.h"
67// socket utility functions
68#include "sock_stuff.h"
69// misc utility functions
70#include "utils.h"
71
72static int libusbmuxd_debug = 0;
73#define DEBUG(x, y, ...) if (x <= libusbmuxd_debug) fprintf(stderr, (y), __VA_ARGS__);
74
75static struct collection devices;
76static usbmuxd_event_cb_t event_cb = NULL;
77#ifdef WIN32
78HANDLE devmon = NULL;
79CRITICAL_SECTION mutex;
80static int mutex_initialized = 0;
81#define LOCK if (!mutex_initialized) { InitializeCriticalSection(&mutex); mutex_initialized = 1; } EnterCriticalSection(&mutex);
82#define UNLOCK LeaveCriticalSection(&mutex);
83#else
84pthread_t devmon;
85pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
86#define LOCK pthread_mutex_lock(&mutex)
87#define UNLOCK pthread_mutex_unlock(&mutex)
88#endif
89static int listenfd = -1;
90
91static int use_tag = 0;
92static int proto_version = 0;
93
94/**
95 * Finds a device info record by its handle.
96 * if the record is not found, NULL is returned.
97 */
98static usbmuxd_device_info_t *devices_find(int handle)
99{
100 FOREACH(usbmuxd_device_info_t *dev, &devices) {
101 if (dev && dev->handle == handle) {
102 return dev;
103 }
104 } ENDFOREACH
105 return NULL;
106}
107
108/**
109 * Creates a socket connection to usbmuxd.
110 * For Mac/Linux it is a unix domain socket,
111 * for Windows it is a tcp socket.
112 */
113static int connect_usbmuxd_socket()
114{
115#if defined(WIN32) || defined(__CYGWIN__)
116 return connect_socket("127.0.0.1", USBMUXD_SOCKET_PORT);
117#else
118 return connect_unix_socket(USBMUXD_SOCKET_FILE);
119#endif
120}
121
122static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload, int timeout)
123{
124 int recv_len;
125 struct usbmuxd_header hdr;
126 char *payload_loc = NULL;
127
128 header->length = 0;
129 header->version = 0;
130 header->message = 0;
131 header->tag = 0;
132
133 recv_len = recv_buf_timeout(sfd, &hdr, sizeof(hdr), 0, timeout);
134 if (recv_len < 0) {
135 return recv_len;
136 } else if (recv_len < sizeof(hdr)) {
137 return recv_len;
138 }
139
140 uint32_t payload_size = hdr.length - sizeof(hdr);
141 if (payload_size > 0) {
142 payload_loc = (char*)malloc(payload_size);
143 if (recv_buf_timeout(sfd, payload_loc, payload_size, 0, 5000) != payload_size) {
144 DEBUG(1, "%s: Error receiving payload of size %d\n", __func__, payload_size);
145 free(payload_loc);
146 return -EBADMSG;
147 }
148 }
149
150#ifdef HAVE_PLIST
151 if (hdr.message == MESSAGE_PLIST) {
152 char *message = NULL;
153 plist_t plist = NULL;
154 plist_from_xml(payload_loc, payload_size, &plist);
155 free(payload_loc);
156
157 if (!plist) {
158 DEBUG(1, "%s: Error getting plist from payload!\n", __func__);
159 return -EBADMSG;
160 }
161
162 plist_t node = plist_dict_get_item(plist, "MessageType");
163 if (plist_get_node_type(node) != PLIST_STRING) {
164 DEBUG(1, "%s: Error getting message type from plist!\n", __func__);
165 free(plist);
166 return -EBADMSG;
167 }
168
169 plist_get_string_val(node, &message);
170 if (message) {
171 uint64_t val = 0;
172 if (strcmp(message, "Result") == 0) {
173 /* result message */
174 uint32_t dwval = 0;
175 plist_t n = plist_dict_get_item(plist, "Number");
176 plist_get_uint_val(n, &val);
177 *payload = malloc(sizeof(uint32_t));
178 dwval = val;
179 memcpy(*payload, &dwval, sizeof(dwval));
180 hdr.length = sizeof(hdr) + sizeof(dwval);
181 hdr.message = MESSAGE_RESULT;
182 } else if (strcmp(message, "Attached") == 0) {
183 /* device add message */
184 struct usbmuxd_device_record *dev = NULL;
185 plist_t props = plist_dict_get_item(plist, "Properties");
186 if (!props) {
187 DEBUG(1, "%s: Could not get properties for message '%s' from plist!\n", __func__, message);
188 free(message);
189 plist_free(plist);
190 return -EBADMSG;
191 }
192 dev = (struct usbmuxd_device_record*)malloc(sizeof(struct usbmuxd_device_record));
193 memset(dev, 0, sizeof(struct usbmuxd_device_record));
194
195 plist_t n = plist_dict_get_item(props, "DeviceID");
196 plist_get_uint_val(n, &val);
197 dev->device_id = (uint32_t)val;
198
199 n = plist_dict_get_item(props, "ProductID");
200 plist_get_uint_val(n, &val);
201 dev->product_id = (uint32_t)val;
202
203 n = plist_dict_get_item(props, "SerialNumber");
204 char *strval = NULL;
205 plist_get_string_val(n, &strval);
206 if (strval) {
207 strncpy(dev->serial_number, strval, 255);
208 free(strval);
209 }
210 n = plist_dict_get_item(props, "LocationID");
211 plist_get_uint_val(n, &val);
212 dev->location = (uint32_t)val;
213 *payload = (void*)dev;
214 hdr.length = sizeof(hdr) + sizeof(struct usbmuxd_device_record);
215 hdr.message = MESSAGE_DEVICE_ADD;
216 } else if (strcmp(message, "Detached") == 0) {
217 /* device remove message */
218 uint32_t dwval = 0;
219 plist_t n = plist_dict_get_item(plist, "DeviceID");
220 if (n) {
221 plist_get_uint_val(n, &val);
222 *payload = malloc(sizeof(uint32_t));
223 dwval = val;
224 memcpy(*payload, &dwval, sizeof(dwval));
225 hdr.length = sizeof(hdr) + sizeof(dwval);
226 hdr.message = MESSAGE_DEVICE_REMOVE;
227 }
228 } else {
229 DEBUG(1, "%s: Unexpected message '%s' in plist!\n", __func__, message);
230 free(message);
231 plist_free(plist);
232 return -EBADMSG;
233 }
234 free(message);
235 }
236 plist_free(plist);
237 } else
238#endif
239 {
240 *payload = payload_loc;
241 }
242
243 memcpy(header, &hdr, sizeof(hdr));
244
245 return hdr.length;
246}
247
248/**
249 * Retrieves the result code to a previously sent request.
250 */
251static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result)
252{
253 struct usbmuxd_header hdr;
254 int recv_len;
255 uint32_t *res = NULL;
256
257 if (!result) {
258 return -EINVAL;
259 }
260 *result = -1;
261
262 if ((recv_len = receive_packet(sfd, &hdr, (void**)&res, 5000)) < 0) {
263 DEBUG(1, "%s: Error receiving packet: %d\n", __func__, errno);
264 if (res)
265 free(res);
266 return -errno;
267 }
268 if (recv_len < sizeof(hdr)) {
269 DEBUG(1, "%s: Received packet is too small!\n", __func__);
270 if (res)
271 free(res);
272 return -EPROTO;
273 }
274
275 if (hdr.message == MESSAGE_RESULT) {
276 int ret = 0;
277 if (res && (hdr.tag == tag)) {
278 memcpy(result, res, sizeof(uint32_t));
279 ret = 1;
280 }
281 if (res)
282 free(res);
283 return ret;
284 }
285 DEBUG(1, "%s: Unexpected message of type %d received!\n", __func__, hdr.message);
286 if (res)
287 free(res);
288 return -EPROTO;
289}
290
291static int send_packet(int sfd, uint32_t message, uint32_t tag, void *payload, uint32_t payload_size)
292{
293 struct usbmuxd_header header;
294
295 header.length = sizeof(struct usbmuxd_header);
296 header.version = proto_version;
297 header.message = message;
298 header.tag = tag;
299 if (payload && (payload_size > 0)) {
300 header.length += payload_size;
301 }
302 int sent = send_buf(sfd, &header, sizeof(header));
303 if (sent != sizeof(header)) {
304 DEBUG(1, "%s: ERROR: could not send packet header\n", __func__);
305 return -1;
306 }
307 if (payload && (payload_size > 0)) {
308 sent += send_buf(sfd, payload, payload_size);
309 }
310 if (sent != (int)header.length) {
311 DEBUG(1, "%s: ERROR: could not send whole packet\n", __func__);
312 close_socket(sfd);
313 return -1;
314 }
315 return sent;
316}
317
318static int send_listen_packet(int sfd, uint32_t tag)
319{
320 int res = 0;
321#ifdef HAVE_PLIST
322 if (proto_version == 1) {
323 /* plist packet */
324 char *payload = NULL;
325 uint32_t payload_size = 0;
326 plist_t plist;
327
328 /* construct message plist */
329 plist = plist_new_dict();
330 plist_dict_insert_item(plist, "BundleID", plist_new_string(PLIST_BUNDLE_ID));
331 plist_dict_insert_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING));
332 plist_dict_insert_item(plist, "MessageType", plist_new_string("Listen"));
333 plist_dict_insert_item(plist, "ProgName", plist_new_string(PLIST_PROGNAME));
334 plist_to_xml(plist, &payload, &payload_size);
335 plist_free(plist);
336
337 res = send_packet(sfd, MESSAGE_PLIST, tag, payload, payload_size);
338 free(payload);
339 } else
340#endif
341 {
342 /* binary packet */
343 res = send_packet(sfd, MESSAGE_LISTEN, tag, NULL, 0);
344 }
345 return res;
346}
347
348static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16_t port)
349{
350 int res = 0;
351#ifdef HAVE_PLIST
352 if (proto_version == 1) {
353 /* plist packet */
354 char *payload = NULL;
355 uint32_t payload_size = 0;
356 plist_t plist;
357
358 /* construct message plist */
359 plist = plist_new_dict();
360 plist_dict_insert_item(plist, "BundleID", plist_new_string(PLIST_BUNDLE_ID));
361 plist_dict_insert_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING));
362 plist_dict_insert_item(plist, "MessageType", plist_new_string("Connect"));
363 plist_dict_insert_item(plist, "DeviceID", plist_new_uint(device_id));
364 plist_dict_insert_item(plist, "PortNumber", plist_new_uint(htons(port)));
365 plist_dict_insert_item(plist, "ProgName", plist_new_string(PLIST_PROGNAME));
366 plist_to_xml(plist, &payload, &payload_size);
367 plist_free(plist);
368
369 res = send_packet(sfd, MESSAGE_PLIST, tag, (void*)payload, payload_size);
370 free(payload);
371 } else
372#endif
373 {
374 /* binary packet */
375 struct {
376 uint32_t device_id;
377 uint16_t port;
378 uint16_t reserved;
379 } conninfo;
380
381 conninfo.device_id = device_id;
382 conninfo.port = htons(port);
383 conninfo.reserved = 0;
384
385 res = send_packet(sfd, MESSAGE_CONNECT, tag, &conninfo, sizeof(conninfo));
386 }
387 return res;
388}
389
390/**
391 * Generates an event, i.e. calls the callback function.
392 * A reference to a populated usbmuxd_event_t with information about the event
393 * and the corresponding device will be passed to the callback function.
394 */
395static void generate_event(usbmuxd_event_cb_t callback, const usbmuxd_device_info_t *dev, enum usbmuxd_event_type event, void *user_data)
396{
397 usbmuxd_event_t ev;
398
399 if (!callback || !dev) {
400 return;
401 }
402
403 ev.event = event;
404 memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t));
405
406 callback(&ev, user_data);
407}
408
409static int usbmuxd_listen_poll()
410{
411 int sfd;
412
413 sfd = connect_usbmuxd_socket();
414 if (sfd < 0) {
415 while (event_cb) {
416 if ((sfd = connect_usbmuxd_socket()) > 0) {
417 break;
418 }
419 sleep(1);
420 }
421 }
422
423 return sfd;
424}
425
426#ifdef HAVE_INOTIFY
427static int use_inotify = 1;
428
429static int usbmuxd_listen_inotify()
430{
431 int inot_fd;
432 int watch_d;
433 int sfd;
434
435 if (!use_inotify) {
436 return -2;
437 }
438
439 sfd = connect_usbmuxd_socket();
440 if (sfd >= 0)
441 return sfd;
442
443 sfd = -1;
444 inot_fd = inotify_init ();
445 if (inot_fd < 0) {
446 DEBUG(1, "%s: Failed to setup inotify\n", __func__);
447 return -2;
448 }
449
450 /* inotify is setup, listen for events that concern us */
451 watch_d = inotify_add_watch (inot_fd, USBMUXD_DIRNAME, IN_CREATE);
452 if (watch_d < 0) {
453 DEBUG(1, "%s: Failed to setup watch descriptor for socket dir\n", __func__);
454 close (inot_fd);
455 return -2;
456 }
457
458 while (1) {
459 ssize_t len, i;
460 char buff[EVENT_BUF_LEN] = {0};
461
462 i = 0;
463 len = read (inot_fd, buff, EVENT_BUF_LEN -1);
464 if (len < 0)
465 goto end;
466 while (i < len) {
467 struct inotify_event *pevent = (struct inotify_event *) & buff[i];
468
469 /* check that it's ours */
470 if (pevent->mask & IN_CREATE &&
471 pevent->len &&
472 pevent->name != NULL &&
473 strcmp(pevent->name, USBMUXD_SOCKET_NAME) == 0) {
474 sfd = connect_usbmuxd_socket ();
475 goto end;
476 }
477 i += EVENT_SIZE + pevent->len;
478 }
479 }
480
481end:
482 inotify_rm_watch(inot_fd, watch_d);
483 close(inot_fd);
484
485 return sfd;
486}
487#endif /* HAVE_INOTIFY */
488
489/**
490 * Tries to connect to usbmuxd and wait if it is not running.
491 */
492static int usbmuxd_listen()
493{
494 int sfd;
495 uint32_t res = -1;
496
497#ifdef HAVE_PLIST
498retry:
499#endif
500
501#ifdef HAVE_INOTIFY
502 sfd = usbmuxd_listen_inotify();
503 if (sfd == -2)
504 sfd = usbmuxd_listen_poll();
505#else
506 sfd = usbmuxd_listen_poll();
507#endif
508
509 if (sfd < 0) {
510 DEBUG(1, "%s: ERROR: usbmuxd was supposed to be running here...\n", __func__);
511 return sfd;
512 }
513
514 use_tag++;
515 LOCK;
516 if (send_listen_packet(sfd, use_tag) <= 0) {
517 UNLOCK;
518 DEBUG(1, "%s: ERROR: could not send listen packet\n", __func__);
519 close_socket(sfd);
520 return -1;
521 }
522 if (usbmuxd_get_result(sfd, use_tag, &res) && (res != 0)) {
523 UNLOCK;
524 close_socket(sfd);
525#ifdef HAVE_PLIST
526 if ((res == RESULT_BADVERSION) && (proto_version != 1)) {
527 proto_version = 1;
528 goto retry;
529 }
530#endif
531 DEBUG(1, "%s: ERROR: did not get OK but %d\n", __func__, res);
532 return -1;
533 }
534 UNLOCK;
535
536 return sfd;
537}
538
539/**
540 * Waits for an event to occur, i.e. a packet coming from usbmuxd.
541 * Calls generate_event to pass the event via callback to the client program.
542 */
543int get_next_event(int sfd, usbmuxd_event_cb_t callback, void *user_data)
544{
545 struct usbmuxd_header hdr;
546 void *payload = NULL;
547
548 /* block until we receive something */
549 if (receive_packet(sfd, &hdr, &payload, 0) < 0) {
550 // when then usbmuxd connection fails,
551 // generate remove events for every device that
552 // is still present so applications know about it
553 FOREACH(usbmuxd_device_info_t *dev, &devices) {
554 generate_event(callback, dev, UE_DEVICE_REMOVE, user_data);
555 collection_remove(&devices, dev);
556 free(dev);
557 } ENDFOREACH
558 return -EIO;
559 }
560
561 if ((hdr.length > sizeof(hdr)) && !payload) {
562 DEBUG(1, "%s: Invalid packet received, payload is missing!\n", __func__);
563 return -EBADMSG;
564 }
565
566 if (hdr.message == MESSAGE_DEVICE_ADD) {
567 struct usbmuxd_device_record *dev = payload;
568 usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
569 if (!devinfo) {
570 DEBUG(1, "%s: Out of memory!\n", __func__);
571 free(payload);
572 return -1;
573 }
574
575 devinfo->handle = dev->device_id;
576 devinfo->product_id = dev->product_id;
577 memset(devinfo->udid, '\0', sizeof(devinfo->udid));
578 memcpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid));
579
580 if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) {
581 sprintf(devinfo->udid + 32, "%08x", devinfo->handle);
582 }
583
584 collection_add(&devices, devinfo);
585 generate_event(callback, devinfo, UE_DEVICE_ADD, user_data);
586 } else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
587 uint32_t handle;
588 usbmuxd_device_info_t *devinfo;
589
590 memcpy(&handle, payload, sizeof(uint32_t));
591
592 devinfo = devices_find(handle);
593 if (!devinfo) {
594 DEBUG(1, "%s: WARNING: got device remove message for handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", __func__, handle);
595 } else {
596 generate_event(callback, devinfo, UE_DEVICE_REMOVE, user_data);
597 collection_remove(&devices, devinfo);
598 free(devinfo);
599 }
600 } else if (hdr.length > 0) {
601 DEBUG(1, "%s: Unexpected message type %d length %d received!\n", __func__, hdr.message, hdr.length);
602 }
603 if (payload) {
604 free(payload);
605 }
606 return 0;
607}
608
609static void device_monitor_cleanup(void* data)
610{
611 FOREACH(usbmuxd_device_info_t *dev, &devices) {
612 collection_remove(&devices, dev);
613 free(dev);
614 } ENDFOREACH
615 collection_free(&devices);
616
617 close_socket(listenfd);
618 listenfd = -1;
619}
620
621/**
622 * Device Monitor thread function.
623 *
624 * This function sets up a connection to usbmuxd
625 */
626static void *device_monitor(void *data)
627{
628 collection_init(&devices);
629
630#ifndef WIN32
631 pthread_cleanup_push(device_monitor_cleanup, NULL);
632#endif
633 while (event_cb) {
634
635 listenfd = usbmuxd_listen();
636 if (listenfd < 0) {
637 continue;
638 }
639
640 while (event_cb) {
641 int res = get_next_event(listenfd, event_cb, data);
642 if (res < 0) {
643 break;
644 }
645 }
646 }
647
648#ifndef WIN32
649 pthread_cleanup_pop(1);
650#else
651 device_monitor_cleanup(NULL);
652#endif
653 return NULL;
654}
655
656int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data)
657{
658 int res;
659
660 if (!callback) {
661 return -EINVAL;
662 }
663 event_cb = callback;
664
665#ifdef WIN32
666 res = 0;
667 devmon = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)device_monitor, user_data, 0, NULL);
668 if (devmon == NULL) {
669 res = GetLastError();
670 }
671#else
672 res = pthread_create(&devmon, NULL, device_monitor, user_data);
673#endif
674 if (res != 0) {
675 DEBUG(1, "%s: ERROR: Could not start device watcher thread!\n", __func__);
676 return res;
677 }
678 return 0;
679}
680
681int usbmuxd_unsubscribe()
682{
683 event_cb = NULL;
684
685 shutdown_socket(listenfd, SHUT_RDWR);
686
687#ifdef WIN32
688 if (devmon != NULL) {
689 WaitForSingleObject(devmon, INFINITE);
690 }
691#else
692 if (pthread_kill(devmon, 0) == 0) {
693 pthread_cancel(devmon);
694 pthread_join(devmon, NULL);
695 }
696#endif
697
698 return 0;
699}
700
701int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list)
702{
703 int sfd;
704 int listen_success = 0;
705 uint32_t res;
706 struct collection tmpdevs;
707 usbmuxd_device_info_t *newlist = NULL;
708 struct usbmuxd_header hdr;
709 struct usbmuxd_device_record *dev;
710 int dev_cnt = 0;
711 void *payload = NULL;
712
713 *device_list = NULL;
714
715#ifdef HAVE_PLIST
716retry:
717#endif
718 sfd = connect_usbmuxd_socket();
719 if (sfd < 0) {
720 DEBUG(1, "%s: error opening socket!\n", __func__);
721 return sfd;
722 }
723
724 use_tag++;
725 LOCK;
726 if (send_listen_packet(sfd, use_tag) > 0) {
727 res = -1;
728 // get response
729 if (usbmuxd_get_result(sfd, use_tag, &res) && (res == 0)) {
730 listen_success = 1;
731 } else {
732 UNLOCK;
733 close_socket(sfd);
734#ifdef HAVE_PLIST
735 if ((res == RESULT_BADVERSION) && (proto_version != 1)) {
736 proto_version = 1;
737 goto retry;
738 }
739#endif
740 DEBUG(1, "%s: Did not get response to scan request (with result=0)...\n", __func__);
741 return res;
742 }
743 }
744
745 if (!listen_success) {
746 UNLOCK;
747 DEBUG(1, "%s: Could not send listen request!\n", __func__);
748 return -1;
749 }
750
751 collection_init(&tmpdevs);
752
753 // receive device list
754 while (1) {
755 if (receive_packet(sfd, &hdr, &payload, 1000) > 0) {
756 if (hdr.message == MESSAGE_DEVICE_ADD) {
757 dev = payload;
758 usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
759 if (!devinfo) {
760 UNLOCK;
761 DEBUG(1, "%s: Out of memory!\n", __func__);
762 free(payload);
763 return -1;
764 }
765
766 devinfo->handle = dev->device_id;
767 devinfo->product_id = dev->product_id;
768 memset(devinfo->udid, '\0', sizeof(devinfo->udid));
769 memcpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid));
770
771 if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) {
772 sprintf(devinfo->udid + 32, "%08x", devinfo->handle);
773 }
774
775 collection_add(&tmpdevs, devinfo);
776
777 } else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
778 uint32_t handle;
779 usbmuxd_device_info_t *devinfo = NULL;
780
781 memcpy(&handle, payload, sizeof(uint32_t));
782
783 FOREACH(usbmuxd_device_info_t *di, &tmpdevs) {
784 if (di && di->handle == handle) {
785 devinfo = di;
786 break;
787 }
788 } ENDFOREACH
789 if (devinfo) {
790 collection_remove(&tmpdevs, devinfo);
791 free(devinfo);
792 }
793 } else {
794 DEBUG(1, "%s: Unexpected message %d\n", __func__, hdr.message);
795 }
796 if (payload)
797 free(payload);
798 } else {
799 // we _should_ have all of them now.
800 // or perhaps an error occured.
801 break;
802 }
803 }
804 UNLOCK;
805
806 // explicitly close connection
807 close_socket(sfd);
808
809 // create copy of device info entries from collection
810 newlist = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t) * (collection_count(&tmpdevs) + 1));
811 dev_cnt = 0;
812 FOREACH(usbmuxd_device_info_t *di, &tmpdevs) {
813 if (di) {
814 memcpy(&newlist[dev_cnt], di, sizeof(usbmuxd_device_info_t));
815 free(di);
816 dev_cnt++;
817 }
818 } ENDFOREACH
819 collection_free(&tmpdevs);
820
821 memset(&newlist[dev_cnt], 0, sizeof(usbmuxd_device_info_t));
822 *device_list = newlist;
823
824 return dev_cnt;
825}
826
827int usbmuxd_device_list_free(usbmuxd_device_info_t **device_list)
828{
829 if (device_list) {
830 free(*device_list);
831 }
832 return 0;
833}
834
835int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device)
836{
837 usbmuxd_device_info_t *dev_list = NULL;
838
839 if (!device) {
840 return -EINVAL;
841 }
842 if (usbmuxd_get_device_list(&dev_list) < 0) {
843 return -ENODEV;
844 }
845
846 int i;
847 int result = 0;
848 for (i = 0; dev_list[i].handle > 0; i++) {
849 if (!udid) {
850 device->handle = dev_list[i].handle;
851 device->product_id = dev_list[i].product_id;
852 strcpy(device->udid, dev_list[i].udid);
853 result = 1;
854 break;
855 }
856 if (!strcmp(udid, dev_list[i].udid)) {
857 device->handle = dev_list[i].handle;
858 device->product_id = dev_list[i].product_id;
859 strcpy(device->udid, dev_list[i].udid);
860 result = 1;
861 break;
862 }
863 }
864
865 free(dev_list);
866
867 return result;
868}
869
870int usbmuxd_connect(const int handle, const unsigned short port)
871{
872 int sfd;
873 int connected = 0;
874 uint32_t res = -1;
875
876#ifdef HAVE_PLIST
877retry:
878#endif
879 sfd = connect_usbmuxd_socket();
880 if (sfd < 0) {
881 DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n",
882 __func__, strerror(errno));
883 return sfd;
884 }
885
886 use_tag++;
887 if (send_connect_packet(sfd, use_tag, (uint32_t)handle, (uint16_t)port) <= 0) {
888 DEBUG(1, "%s: Error sending connect message!\n", __func__);
889 } else {
890 // read ACK
891 DEBUG(2, "%s: Reading connect result...\n", __func__);
892 if (usbmuxd_get_result(sfd, use_tag, &res)) {
893 if (res == 0) {
894 DEBUG(2, "%s: Connect success!\n", __func__);
895 connected = 1;
896 } else {
897#ifdef HAVE_PLIST
898 if ((res == RESULT_BADVERSION) && (proto_version == 0)) {
899 proto_version = 1;
900 close_socket(sfd);
901 goto retry;
902 }
903#endif
904 DEBUG(1, "%s: Connect failed, Error code=%d\n", __func__, res);
905 }
906 }
907 }
908
909 if (connected) {
910 return sfd;
911 }
912
913 close_socket(sfd);
914
915 return -1;
916}
917
918int usbmuxd_disconnect(int sfd)
919{
920 return close_socket(sfd);
921}
922
923int usbmuxd_send(int sfd, const char *data, uint32_t len, uint32_t *sent_bytes)
924{
925 int num_sent;
926
927 if (sfd < 0) {
928 return -EINVAL;
929 }
930
931 num_sent = send(sfd, (void*)data, len, 0);
932 if (num_sent < 0) {
933 *sent_bytes = 0;
934 DEBUG(1, "%s: Error %d when sending: %s\n", __func__, num_sent, strerror(errno));
935 return num_sent;
936 } else if ((uint32_t)num_sent < len) {
937 DEBUG(1, "%s: Warning: Did not send enough (only %d of %d)\n", __func__, num_sent, len);
938 }
939
940 *sent_bytes = num_sent;
941
942 return 0;
943}
944
945int usbmuxd_recv_timeout(int sfd, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
946{
947 int num_recv = recv_buf_timeout(sfd, (void*)data, len, 0, timeout);
948 if (num_recv < 0) {
949 *recv_bytes = 0;
950 return num_recv;
951 }
952
953 *recv_bytes = num_recv;
954
955 return 0;
956}
957
958int usbmuxd_recv(int sfd, char *data, uint32_t len, uint32_t *recv_bytes)
959{
960 return usbmuxd_recv_timeout(sfd, data, len, recv_bytes, 5000);
961}
962
963void libusbmuxd_set_use_inotify(int set)
964{
965#ifdef HAVE_INOTIFY
966 use_inotify = set;
967#endif
968 return;
969}
970
971void libusbmuxd_set_debug_level(int level)
972{
973 libusbmuxd_debug = level;
974 sock_stuff_set_verbose(level);
975}
diff --git a/libusbmuxd/sock_stuff.c b/libusbmuxd/sock_stuff.c
deleted file mode 100644
index 609c8ad..0000000
--- a/libusbmuxd/sock_stuff.c
+++ /dev/null
@@ -1,375 +0,0 @@
1/*
2 libusbmuxd - client library to talk to usbmuxd
3
4Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
5Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
6Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com>
7
8This library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as
10published by the Free Software Foundation, either version 2.1 of the
11License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
24#include <stdio.h>
25#include <stddef.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <errno.h>
30#include <sys/time.h>
31#include <sys/stat.h>
32#ifdef WIN32
33#include <windows.h>
34#include <winsock2.h>
35static int wsa_init = 0;
36#else
37#include <sys/socket.h>
38#include <sys/un.h>
39#include <netinet/in.h>
40#include <netdb.h>
41#include <arpa/inet.h>
42#endif
43#include "sock_stuff.h"
44
45#define RECV_TIMEOUT 20000
46
47static int verbose = 0;
48
49void sock_stuff_set_verbose(int level)
50{
51 verbose = level;
52}
53
54#ifndef WIN32
55int create_unix_socket(const char *filename)
56{
57 struct sockaddr_un name;
58 int sock;
59 size_t size;
60
61 // remove if still present
62 unlink(filename);
63
64 /* Create the socket. */
65 sock = socket(PF_LOCAL, SOCK_STREAM, 0);
66 if (sock < 0) {
67 perror("socket");
68 return -1;
69 }
70
71 /* Bind a name to the socket. */
72 name.sun_family = AF_LOCAL;
73 strncpy(name.sun_path, filename, sizeof(name.sun_path));
74 name.sun_path[sizeof(name.sun_path) - 1] = '\0';
75
76 /* The size of the address is
77 the offset of the start of the filename,
78 plus its length,
79 plus one for the terminating null byte.
80 Alternatively you can just do:
81 size = SUN_LEN (&name);
82 */
83 size = (offsetof(struct sockaddr_un, sun_path)
84 + strlen(name.sun_path) + 1);
85
86 if (bind(sock, (struct sockaddr *) &name, size) < 0) {
87 perror("bind");
88 close_socket(sock);
89 return -1;
90 }
91
92 if (listen(sock, 10) < 0) {
93 perror("listen");
94 close_socket(sock);
95 return -1;
96 }
97
98 return sock;
99}
100
101int connect_unix_socket(const char *filename)
102{
103 struct sockaddr_un name;
104 int sfd = -1;
105 size_t size;
106 struct stat fst;
107
108 // check if socket file exists...
109 if (stat(filename, &fst) != 0) {
110 if (verbose >= 2)
111 fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename,
112 strerror(errno));
113 return -1;
114 }
115 // ... and if it is a unix domain socket
116 if (!S_ISSOCK(fst.st_mode)) {
117 if (verbose >= 2)
118 fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__,
119 filename);
120 return -1;
121 }
122 // make a new socket
123 if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
124 if (verbose >= 2)
125 fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno));
126 return -1;
127 }
128 // and connect to 'filename'
129 name.sun_family = AF_LOCAL;
130 strncpy(name.sun_path, filename, sizeof(name.sun_path));
131 name.sun_path[sizeof(name.sun_path) - 1] = 0;
132
133 size = (offsetof(struct sockaddr_un, sun_path)
134 + strlen(name.sun_path) + 1);
135
136 if (connect(sfd, (struct sockaddr *) &name, size) < 0) {
137 close_socket(sfd);
138 if (verbose >= 2)
139 fprintf(stderr, "%s: connect: %s\n", __func__,
140 strerror(errno));
141 return -1;
142 }
143
144 return sfd;
145}
146#endif
147
148int create_socket(uint16_t port)
149{
150 int sfd = -1;
151 int yes = 1;
152#ifdef WIN32
153 WSADATA wsa_data;
154 if (!wsa_init) {
155 if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
156 fprintf(stderr, "WSAStartup failed!\n");
157 ExitProcess(-1);
158 }
159 wsa_init = 1;
160 }
161#endif
162 struct sockaddr_in saddr;
163
164 if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
165 perror("socket()");
166 return -1;
167 }
168
169 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
170 perror("setsockopt()");
171 close_socket(sfd);
172 return -1;
173 }
174
175 memset((void *) &saddr, 0, sizeof(saddr));
176 saddr.sin_family = AF_INET;
177 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
178 saddr.sin_port = htons(port);
179
180 if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) {
181 perror("bind()");
182 close_socket(sfd);
183 return -1;
184 }
185
186 if (listen(sfd, 1) == -1) {
187 perror("listen()");
188 close_socket(sfd);
189 return -1;
190 }
191
192 return sfd;
193}
194
195#if defined(WIN32) || defined(__CYGWIN__)
196int connect_socket(const char *addr, uint16_t port)
197{
198 int sfd = -1;
199 int yes = 1;
200 struct hostent *hp;
201 struct sockaddr_in saddr;
202#ifdef WIN32
203 WSADATA wsa_data;
204 if (!wsa_init) {
205 if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
206 fprintf(stderr, "WSAStartup failed!\n");
207 ExitProcess(-1);
208 }
209 wsa_init = 1;
210 }
211#endif
212
213 if (!addr) {
214 errno = EINVAL;
215 return -1;
216 }
217
218 if ((hp = gethostbyname(addr)) == NULL) {
219 if (verbose >= 2)
220 fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr);
221 return -1;
222 }
223
224 if (!hp->h_addr) {
225 if (verbose >= 2)
226 fprintf(stderr, "%s: gethostbyname returned NULL address!\n",
227 __func__);
228 return -1;
229 }
230
231 if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
232 perror("socket()");
233 return -1;
234 }
235
236 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
237 perror("setsockopt()");
238 close_socket(sfd);
239 return -1;
240 }
241
242 memset((void *) &saddr, 0, sizeof(saddr));
243 saddr.sin_family = AF_INET;
244 saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr;
245 saddr.sin_port = htons(port);
246
247 if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
248 perror("connect");
249 close_socket(sfd);
250 return -2;
251 }
252
253 return sfd;
254}
255#endif /* WIN32 || __CYGWIN__ */
256
257int check_fd(int fd, fd_mode fdm, unsigned int timeout)
258{
259 fd_set fds;
260 int sret;
261 int eagain;
262 struct timeval to;
263 struct timeval *pto;
264
265 if (fd <= 0) {
266 if (verbose >= 2)
267 fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd);
268 return -1;
269 }
270
271 FD_ZERO(&fds);
272 FD_SET(fd, &fds);
273
274 if (timeout > 0) {
275 to.tv_sec = (time_t) (timeout / 1000);
276 to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000);
277 pto = &to;
278 } else {
279 pto = NULL;
280 }
281
282 sret = -1;
283
284 do {
285 eagain = 0;
286 switch (fdm) {
287 case FDM_READ:
288 sret = select(fd + 1, &fds, NULL, NULL, pto);
289 break;
290 case FDM_WRITE:
291 sret = select(fd + 1, NULL, &fds, NULL, pto);
292 break;
293 case FDM_EXCEPT:
294 sret = select(fd + 1, NULL, NULL, &fds, pto);
295 break;
296 default:
297 return -1;
298 }
299
300 if (sret < 0) {
301 switch (errno) {
302 case EINTR:
303 // interrupt signal in select
304 if (verbose >= 2)
305 fprintf(stderr, "%s: EINTR\n", __func__);
306 eagain = 1;
307 break;
308 case EAGAIN:
309 if (verbose >= 2)
310 fprintf(stderr, "%s: EAGAIN\n", __func__);
311 break;
312 default:
313 if (verbose >= 2)
314 fprintf(stderr, "%s: select failed: %s\n", __func__,
315 strerror(errno));
316 return -1;
317 }
318 }
319 } while (eagain);
320
321 return sret;
322}
323
324int shutdown_socket(int fd, int how)
325{
326 return shutdown(fd, how);
327}
328
329int close_socket(int fd) {
330#ifdef WIN32
331 return closesocket(fd);
332#else
333 return close(fd);
334#endif
335}
336
337int recv_buf(int fd, void *data, size_t length)
338{
339 return recv_buf_timeout(fd, data, length, 0, RECV_TIMEOUT);
340}
341
342int peek_buf(int fd, void *data, size_t length)
343{
344 return recv_buf_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT);
345}
346
347int recv_buf_timeout(int fd, void *data, size_t length, int flags,
348 unsigned int timeout)
349{
350 int res;
351 int result;
352
353 // check if data is available
354 res = check_fd(fd, FDM_READ, timeout);
355 if (res <= 0) {
356 return res;
357 }
358 // if we get here, there _is_ data available
359 result = recv(fd, data, length, flags);
360 if (res > 0 && result == 0) {
361 // but this is an error condition
362 if (verbose >= 3)
363 fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd);
364 return -EAGAIN;
365 }
366 if (result < 0) {
367 return -errno;
368 }
369 return result;
370}
371
372int send_buf(int fd, void *data, size_t length)
373{
374 return send(fd, data, length, 0);
375}
diff --git a/libusbmuxd/sock_stuff.h b/libusbmuxd/sock_stuff.h
deleted file mode 100644
index 5efcd27..0000000
--- a/libusbmuxd/sock_stuff.h
+++ /dev/null
@@ -1,65 +0,0 @@
1/*
2 libusbmuxd - client library to talk to usbmuxd
3
4Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
5Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
6Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com>
7
8This library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as
10published by the Free Software Foundation, either version 2.1 of the
11License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
24#ifndef __SOCK_STUFF_H
25#define __SOCK_STUFF_H
26
27#include <stdint.h>
28
29enum fd_mode {
30 FDM_READ,
31 FDM_WRITE,
32 FDM_EXCEPT
33};
34typedef enum fd_mode fd_mode;
35
36#ifdef WIN32
37#include <winsock2.h>
38#define SHUT_RD SD_READ
39#define SHUT_WR SD_WRITE
40#define SHUT_RDWR SD_BOTH
41#endif
42
43#ifndef WIN32
44int create_unix_socket(const char *filename);
45int connect_unix_socket(const char *filename);
46#endif
47int create_socket(uint16_t port);
48#if defined(WIN32) || defined(__CYGWIN__)
49int connect_socket(const char *addr, uint16_t port);
50#endif
51int check_fd(int fd, fd_mode fdm, unsigned int timeout);
52
53int shutdown_socket(int fd, int how);
54int close_socket(int fd);
55
56int recv_buf(int fd, void *data, size_t size);
57int peek_buf(int fd, void *data, size_t size);
58int recv_buf_timeout(int fd, void *data, size_t size, int flags,
59 unsigned int timeout);
60
61int send_buf(int fd, void *data, size_t size);
62
63void sock_stuff_set_verbose(int level);
64
65#endif /* __SOCK_STUFF_H */
diff --git a/libusbmuxd/usbmuxd-proto.h b/libusbmuxd/usbmuxd-proto.h
deleted file mode 100644
index be9e709..0000000
--- a/libusbmuxd/usbmuxd-proto.h
+++ /dev/null
@@ -1,97 +0,0 @@
1/*
2 libusbmuxd - client library to talk to usbmuxd
3
4Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
5Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
6Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com>
7
8This library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as
10published by the Free Software Foundation, either version 2.1 of the
11License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
24/* Protocol defintion for usbmuxd proxy protocol */
25#ifndef __USBMUXD_PROTO_H
26#define __USBMUXD_PROTO_H
27
28#include <stdint.h>
29#define USBMUXD_PROTOCOL_VERSION 0
30
31#if defined(WIN32) || defined(__CYGWIN__)
32#define USBMUXD_SOCKET_PORT 27015
33#else
34#define USBMUXD_SOCKET_FILE "/var/run/usbmuxd"
35#endif
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41enum usbmuxd_result {
42 RESULT_OK = 0,
43 RESULT_BADCOMMAND = 1,
44 RESULT_BADDEV = 2,
45 RESULT_CONNREFUSED = 3,
46 // ???
47 // ???
48 RESULT_BADVERSION = 6,
49};
50
51enum usbmuxd_msgtype {
52 MESSAGE_RESULT = 1,
53 MESSAGE_CONNECT = 2,
54 MESSAGE_LISTEN = 3,
55 MESSAGE_DEVICE_ADD = 4,
56 MESSAGE_DEVICE_REMOVE = 5,
57 //???
58 //???
59 MESSAGE_PLIST = 8,
60};
61
62struct usbmuxd_header {
63 uint32_t length; // length of message, including header
64 uint32_t version; // protocol version
65 uint32_t message; // message type
66 uint32_t tag; // responses to this query will echo back this tag
67} __attribute__((__packed__));
68
69struct usbmuxd_result_msg {
70 struct usbmuxd_header header;
71 uint32_t result;
72} __attribute__((__packed__));
73
74struct usbmuxd_connect_request {
75 struct usbmuxd_header header;
76 uint32_t device_id;
77 uint16_t port; // TCP port number
78 uint16_t reserved; // set to zero
79} __attribute__((__packed__));
80
81struct usbmuxd_listen_request {
82 struct usbmuxd_header header;
83} __attribute__((__packed__));
84
85struct usbmuxd_device_record {
86 uint32_t device_id;
87 uint16_t product_id;
88 char serial_number[256];
89 uint16_t padding;
90 uint32_t location;
91} __attribute__((__packed__));
92
93#ifdef __cplusplus
94}
95#endif
96
97#endif /* __USBMUXD_PROTO_H */
diff --git a/libusbmuxd/usbmuxd.h b/libusbmuxd/usbmuxd.h
deleted file mode 100644
index 0f7b862..0000000
--- a/libusbmuxd/usbmuxd.h
+++ /dev/null
@@ -1,191 +0,0 @@
1/*
2 libusbmuxd - client library to talk to usbmuxd
3
4Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
5Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
6Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com>
7
8This library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as
10published by the Free Software Foundation, either version 2.1 of the
11License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
24#ifndef __USBMUXD_H
25#define __USBMUXD_H
26#include <stdint.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 * Device information structure holding data to identify the device.
34 * The relevant 'handle' should be passed to 'usbmuxd_connect()', to
35 * start a proxy connection. The value 'handle' should be considered
36 * opaque and no presumption made about the meaning of its value.
37 */
38typedef struct {
39 int handle;
40 int product_id;
41 char udid[41];
42} usbmuxd_device_info_t;
43
44/**
45 * event types for event callback function
46 */
47enum usbmuxd_event_type {
48 UE_DEVICE_ADD = 1,
49 UE_DEVICE_REMOVE
50};
51
52/**
53 * Event structure that will be passed to the callback function.
54 * 'event' will contains the type of the event, and 'device' will contains
55 * information about the device.
56 */
57typedef struct {
58 int event;
59 usbmuxd_device_info_t device;
60} usbmuxd_event_t;
61
62/**
63 * Callback function prototype.
64 */
65typedef void (*usbmuxd_event_cb_t) (const usbmuxd_event_t *event, void *user_data);
66
67/**
68 * Subscribe a callback function so that applications get to know about
69 * device add/remove events.
70 *
71 * @param callback A callback function that is executed when an event occurs.
72 *
73 * @return 0 on success or negative on error.
74 */
75int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data);
76
77/**
78 * Unsubscribe callback.
79 *
80 * @return only 0 for now.
81 */
82int usbmuxd_unsubscribe();
83
84/**
85 * Contacts usbmuxd and retrieves a list of connected devices.
86 *
87 * @param device_list A pointer to an array of usbmuxd_device_info_t
88 * that will hold records of the connected devices. The last record
89 * is a null-terminated record with all fields set to 0/NULL.
90 * @note The user has to free the list returned.
91 *
92 * @return number of attached devices, zero on no devices, or negative
93 * if an error occured.
94 */
95int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list);
96
97/**
98 * Frees the device list returned by an usbmuxd_get_device_list call
99 *
100 * @param device_list A pointer to an array of usbmuxd_device_info_t to free.
101 *
102 * @return 0 on success, -1 on error.
103 */
104int usbmuxd_device_list_free(usbmuxd_device_info_t **device_list);
105
106/**
107 * Gets device information for the device specified by udid.
108 *
109 * @param udid A device UDID of the device to look for. If udid is NULL,
110 * This function will return the first device found.
111 * @param device Pointer to a previously allocated (or static)
112 * usbmuxd_device_info_t that will be filled with the device info.
113 *
114 * @return 0 if no matching device is connected, 1 if the device was found,
115 * or a negative value on error.
116 */
117int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device);
118
119/**
120 * Request proxy connect to
121 *
122 * @param handle returned by 'usbmuxd_scan()'
123 *
124 * @param tcp_port TCP port number on device, in range 0-65535.
125 * common values are 62078 for lockdown, and 22 for SSH.
126 *
127 * @return file descriptor socket of the connection, or -1 on error
128 */
129int usbmuxd_connect(const int handle, const unsigned short tcp_port);
130
131/**
132 * Disconnect. For now, this just closes the socket file descriptor.
133 *
134 * @param sfd socker file descriptor returned by usbmuxd_connect()
135 *
136 * @return 0 on success, -1 on error.
137 */
138int usbmuxd_disconnect(int sfd);
139
140/**
141 * Send data to the specified socket.
142 *
143 * @param sfd socket file descriptor returned by usbmuxd_connect()
144 * @param data buffer to send
145 * @param len size of buffer to send
146 * @param sent_bytes how many bytes sent
147 *
148 * @return 0 on success, a negative errno value otherwise.
149 */
150int usbmuxd_send(int sfd, const char *data, uint32_t len, uint32_t *sent_bytes);
151
152/**
153 * Receive data from the specified socket.
154 *
155 * @param sfd socket file descriptor returned by usbmuxd_connect()
156 * @param data buffer to put the data to
157 * @param len number of bytes to receive
158 * @param recv_bytes number of bytes received
159 * @param timeout how many milliseconds to wait for data
160 *
161 * @return 0 on success, a negative errno value otherwise.
162 */
163int usbmuxd_recv_timeout(int sfd, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout);
164
165/**
166 * Receive data from the specified socket with a default timeout.
167 *
168 * @param sfd socket file descriptor returned by usbmuxd_connect()
169 * @param data buffer to put the data to
170 * @param len number of bytes to receive
171 * @param recv_bytes number of bytes received
172 *
173 * @return 0 on success, a negative errno value otherwise.
174 */
175int usbmuxd_recv(int sfd, char *data, uint32_t len, uint32_t *recv_bytes);
176
177/**
178 * Enable or disable the use of inotify extension. Enabled by default.
179 * Use 0 to disable and 1 to enable inotify support.
180 * This only has an effect on linux systems if inotify support has been built
181 * in. Otherwise and on all other platforms this function has no effect.
182 */
183void libusbmuxd_set_use_inotify(int set);
184
185void libusbmuxd_set_debug_level(int level);
186
187#ifdef __cplusplus
188}
189#endif
190
191#endif /* __USBMUXD_H */
diff --git a/m4/as-compiler-flag.m4 b/m4/as-compiler-flag.m4
new file mode 100644
index 0000000..0f660cf
--- /dev/null
+++ b/m4/as-compiler-flag.m4
@@ -0,0 +1,62 @@
1dnl as-compiler-flag.m4 0.1.0
2
3dnl autostars m4 macro for detection of compiler flags
4
5dnl David Schleef <ds@schleef.org>
6
7dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $
8
9dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
10dnl Tries to compile with the given CFLAGS.
11dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
12dnl and ACTION-IF-NOT-ACCEPTED otherwise.
13
14AC_DEFUN([AS_COMPILER_FLAG],
15[
16 AC_MSG_CHECKING([to see if compiler understands $1])
17
18 save_CFLAGS="$CFLAGS"
19 CFLAGS="$CFLAGS $1"
20
21 AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
22 CFLAGS="$save_CFLAGS"
23
24 if test "X$flag_ok" = Xyes ; then
25 m4_ifvaln([$2],[$2])
26 true
27 else
28 m4_ifvaln([$3],[$3])
29 true
30 fi
31 AC_MSG_RESULT([$flag_ok])
32])
33
34dnl AS_COMPILER_FLAGS(VAR, FLAGS)
35dnl Tries to compile with the given CFLAGS.
36
37AC_DEFUN([AS_COMPILER_FLAGS],
38[
39 list=$2
40 flags_supported=""
41 flags_unsupported=""
42 AC_MSG_CHECKING([for supported compiler flags])
43 for each in $list
44 do
45 save_CFLAGS="$CFLAGS"
46 CFLAGS="$CFLAGS $each"
47 AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
48 CFLAGS="$save_CFLAGS"
49
50 if test "X$flag_ok" = Xyes ; then
51 flags_supported="$flags_supported $each"
52 else
53 flags_unsupported="$flags_unsupported $each"
54 fi
55 done
56 AC_MSG_RESULT([$flags_supported])
57 if test "X$flags_unsupported" != X ; then
58 AC_MSG_WARN([unsupported compiler flags: $flags_unsupported])
59 fi
60 $1="$$1 $flags_supported"
61])
62
diff --git a/python-client/.gitignore b/python-client/.gitignore
deleted file mode 100644
index 5da7ef5..0000000
--- a/python-client/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
1*.pyc
2*.pyo
3
diff --git a/python-client/tcprelay.py b/python-client/tcprelay.py
deleted file mode 100644
index add200c..0000000
--- a/python-client/tcprelay.py
+++ /dev/null
@@ -1,148 +0,0 @@
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3#
4# tcprelay.py - TCP connection relay for usbmuxd
5#
6# Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com>
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 2 or version 3.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21import usbmux
22import SocketServer
23import select
24from optparse import OptionParser
25import sys
26import threading
27
28class SocketRelay(object):
29 def __init__(self, a, b, maxbuf=65535):
30 self.a = a
31 self.b = b
32 self.atob = ""
33 self.btoa = ""
34 self.maxbuf = maxbuf
35 def handle(self):
36 while True:
37 rlist = []
38 wlist = []
39 xlist = [self.a, self.b]
40 if self.atob:
41 wlist.append(self.b)
42 if self.btoa:
43 wlist.append(self.a)
44 if len(self.atob) < self.maxbuf:
45 rlist.append(self.a)
46 if len(self.btoa) < self.maxbuf:
47 rlist.append(self.b)
48 rlo, wlo, xlo = select.select(rlist, wlist, xlist)
49 if xlo:
50 return
51 if self.a in wlo:
52 n = self.a.send(self.btoa)
53 self.btoa = self.btoa[n:]
54 if self.b in wlo:
55 n = self.b.send(self.atob)
56 self.atob = self.atob[n:]
57 if self.a in rlo:
58 s = self.a.recv(self.maxbuf - len(self.atob))
59 if not s:
60 return
61 self.atob += s
62 if self.b in rlo:
63 s = self.b.recv(self.maxbuf - len(self.btoa))
64 if not s:
65 return
66 self.btoa += s
67 #print "Relay iter: %8d atob, %8d btoa, lists: %r %r %r"%(len(self.atob), len(self.btoa), rlo, wlo, xlo)
68
69class TCPRelay(SocketServer.BaseRequestHandler):
70 def handle(self):
71 print "Incoming connection to %d"%self.server.server_address[1]
72 mux = usbmux.USBMux(options.sockpath)
73 print "Waiting for devices..."
74 if not mux.devices:
75 mux.process(1.0)
76 if not mux.devices:
77 print "No device found"
78 self.request.close()
79 return
80 dev = mux.devices[0]
81 print "Connecting to device %s"%str(dev)
82 dsock = mux.connect(dev, self.server.rport)
83 lsock = self.request
84 print "Connection established, relaying data"
85 try:
86 fwd = SocketRelay(dsock, lsock, self.server.bufsize * 1024)
87 fwd.handle()
88 finally:
89 dsock.close()
90 lsock.close()
91 print "Connection closed"
92
93class TCPServer(SocketServer.TCPServer):
94 allow_reuse_address = True
95
96class ThreadedTCPServer(SocketServer.ThreadingMixIn, TCPServer):
97 pass
98
99HOST = "localhost"
100
101parser = OptionParser(usage="usage: %prog [OPTIONS] RemotePort[:LocalPort] [RemotePort[:LocalPort]]...")
102parser.add_option("-t", "--threaded", dest='threaded', action='store_true', default=False, help="use threading to handle multiple connections at once")
103parser.add_option("-b", "--bufsize", dest='bufsize', action='store', metavar='KILOBYTES', type='int', default=128, help="specify buffer size for socket forwarding")
104parser.add_option("-s", "--socket", dest='sockpath', action='store', metavar='PATH', type='str', default=None, help="specify the path of the usbmuxd socket")
105
106options, args = parser.parse_args()
107
108serverclass = TCPServer
109if options.threaded:
110 serverclass = ThreadedTCPServer
111
112if len(args) == 0:
113 parser.print_help()
114 sys.exit(1)
115
116ports = []
117
118for arg in args:
119 try:
120 if ':' in arg:
121 rport, lport = arg.split(":")
122 rport = int(rport)
123 lport = int(lport)
124 ports.append((rport, lport))
125 else:
126 ports.append((int(arg), int(arg)))
127 except:
128 parser.print_help()
129 sys.exit(1)
130
131servers=[]
132
133for rport, lport in ports:
134 print "Forwarding local port %d to remote port %d"%(lport, rport)
135 server = serverclass((HOST, lport), TCPRelay)
136 server.rport = rport
137 server.bufsize = options.bufsize
138 servers.append(server)
139
140alive = True
141
142while alive:
143 try:
144 rl, wl, xl = select.select(servers, [], [])
145 for server in rl:
146 server.handle_request()
147 except:
148 alive = False
diff --git a/python-client/usbmux.py b/python-client/usbmux.py
deleted file mode 100644
index 79ec26a..0000000
--- a/python-client/usbmux.py
+++ /dev/null
@@ -1,246 +0,0 @@
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3#
4# usbmux.py - usbmux client library for Python
5#
6# Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com>
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 2 or version 3.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21import socket, struct, select, sys
22
23try:
24 import plistlib
25 haveplist = True
26except:
27 haveplist = False
28
29class MuxError(Exception):
30 pass
31
32class MuxVersionError(MuxError):
33 pass
34
35class SafeStreamSocket:
36 def __init__(self, address, family):
37 self.sock = socket.socket(family, socket.SOCK_STREAM)
38 self.sock.connect(address)
39 def send(self, msg):
40 totalsent = 0
41 while totalsent < len(msg):
42 sent = self.sock.send(msg[totalsent:])
43 if sent == 0:
44 raise MuxError("socket connection broken")
45 totalsent = totalsent + sent
46 def recv(self, size):
47 msg = ''
48 while len(msg) < size:
49 chunk = self.sock.recv(size-len(msg))
50 if chunk == '':
51 raise MuxError("socket connection broken")
52 msg = msg + chunk
53 return msg
54
55class MuxDevice(object):
56 def __init__(self, devid, usbprod, serial, location):
57 self.devid = devid
58 self.usbprod = usbprod
59 self.serial = serial
60 self.location = location
61 def __str__(self):
62 return "<MuxDevice: ID %d ProdID 0x%04x Serial '%s' Location 0x%x>"%(self.devid, self.usbprod, self.serial, self.location)
63
64class BinaryProtocol(object):
65 TYPE_RESULT = 1
66 TYPE_CONNECT = 2
67 TYPE_LISTEN = 3
68 TYPE_DEVICE_ADD = 4
69 TYPE_DEVICE_REMOVE = 5
70 VERSION = 0
71 def __init__(self, socket):
72 self.socket = socket
73 self.connected = False
74
75 def _pack(self, req, payload):
76 if req == self.TYPE_CONNECT:
77 return struct.pack("IH", payload['DeviceID'], payload['PortNumber']) + "\x00\x00"
78 elif req == self.TYPE_LISTEN:
79 return ""
80 else:
81 raise ValueError("Invalid outgoing request type %d"%req)
82
83 def _unpack(self, resp, payload):
84 if resp == self.TYPE_RESULT:
85 return {'Number':struct.unpack("I", payload)[0]}
86 elif resp == self.TYPE_DEVICE_ADD:
87 devid, usbpid, serial, pad, location = struct.unpack("IH256sHI", payload)
88 serial = serial.split("\0")[0]
89 return {'DeviceID': devid, 'Properties': {'LocationID': location, 'SerialNumber': serial, 'ProductID': usbpid}}
90 elif resp == self.TYPE_DEVICE_REMOVE:
91 devid = struct.unpack("I", payload)[0]
92 return {'DeviceID': devid}
93 else:
94 raise MuxError("Invalid incoming request type %d"%req)
95
96 def sendpacket(self, req, tag, payload={}):
97 payload = self._pack(req, payload)
98 if self.connected:
99 raise MuxError("Mux is connected, cannot issue control packets")
100 length = 16 + len(payload)
101 data = struct.pack("IIII", length, self.VERSION, req, tag) + payload
102 self.socket.send(data)
103 def getpacket(self):
104 if self.connected:
105 raise MuxError("Mux is connected, cannot issue control packets")
106 dlen = self.socket.recv(4)
107 dlen = struct.unpack("I", dlen)[0]
108 body = self.socket.recv(dlen - 4)
109 version, resp, tag = struct.unpack("III",body[:0xc])
110 if version != self.VERSION:
111 raise MuxVersionError("Version mismatch: expected %d, got %d"%(self.VERSION,version))
112 payload = self._unpack(resp, body[0xc:])
113 return (resp, tag, payload)
114
115class PlistProtocol(BinaryProtocol):
116 TYPE_RESULT = "Result"
117 TYPE_CONNECT = "Connect"
118 TYPE_LISTEN = "Listen"
119 TYPE_DEVICE_ADD = "Attached"
120 TYPE_DEVICE_REMOVE = "Detached" #???
121 TYPE_PLIST = 8
122 VERSION = 1
123 def __init__(self, socket):
124 if not haveplist:
125 raise Exception("You need the plistlib module")
126 BinaryProtocol.__init__(self, socket)
127
128 def _pack(self, req, payload):
129 return payload
130
131 def _unpack(self, resp, payload):
132 return payload
133
134 def sendpacket(self, req, tag, payload={}):
135 payload['ClientVersionString'] = 'usbmux.py by marcan'
136 if isinstance(req, int):
137 req = [self.TYPE_CONNECT, self.TYPE_LISTEN][req-2]
138 payload['MessageType'] = req
139 payload['ProgName'] = 'tcprelay'
140 BinaryProtocol.sendpacket(self, self.TYPE_PLIST, tag, plistlib.writePlistToString(payload))
141 def getpacket(self):
142 resp, tag, payload = BinaryProtocol.getpacket(self)
143 if resp != self.TYPE_PLIST:
144 raise MuxError("Received non-plist type %d"%resp)
145 payload = plistlib.readPlistFromString(payload)
146 return payload['MessageType'], tag, payload
147
148class MuxConnection(object):
149 def __init__(self, socketpath, protoclass):
150 self.socketpath = socketpath
151 if sys.platform in ['win32', 'cygwin']:
152 family = socket.AF_INET
153 address = ('127.0.0.1', 27015)
154 else:
155 family = socket.AF_UNIX
156 address = self.socketpath
157 self.socket = SafeStreamSocket(address, family)
158 self.proto = protoclass(self.socket)
159 self.pkttag = 1
160 self.devices = []
161
162 def _getreply(self):
163 while True:
164 resp, tag, data = self.proto.getpacket()
165 if resp == self.proto.TYPE_RESULT:
166 return tag, data
167 else:
168 raise MuxError("Invalid packet type received: %d"%resp)
169 def _processpacket(self):
170 resp, tag, data = self.proto.getpacket()
171 if resp == self.proto.TYPE_DEVICE_ADD:
172 self.devices.append(MuxDevice(data['DeviceID'], data['Properties']['ProductID'], data['Properties']['SerialNumber'], data['Properties']['LocationID']))
173 elif resp == self.proto.TYPE_DEVICE_REMOVE:
174 for dev in self.devices:
175 if dev.devid == data['DeviceID']:
176 self.devices.remove(dev)
177 elif resp == self.proto.TYPE_RESULT:
178 raise MuxError("Unexpected result: %d"%resp)
179 else:
180 raise MuxError("Invalid packet type received: %d"%resp)
181 def _exchange(self, req, payload={}):
182 mytag = self.pkttag
183 self.pkttag += 1
184 self.proto.sendpacket(req, mytag, payload)
185 recvtag, data = self._getreply()
186 if recvtag != mytag:
187 raise MuxError("Reply tag mismatch: expected %d, got %d"%(mytag, recvtag))
188 return data['Number']
189
190 def listen(self):
191 ret = self._exchange(self.proto.TYPE_LISTEN)
192 if ret != 0:
193 raise MuxError("Listen failed: error %d"%ret)
194 def process(self, timeout=None):
195 if self.proto.connected:
196 raise MuxError("Socket is connected, cannot process listener events")
197 rlo, wlo, xlo = select.select([self.socket.sock], [], [self.socket.sock], timeout)
198 if xlo:
199 self.socket.sock.close()
200 raise MuxError("Exception in listener socket")
201 if rlo:
202 self._processpacket()
203 def connect(self, device, port):
204 ret = self._exchange(self.proto.TYPE_CONNECT, {'DeviceID':device.devid, 'PortNumber':((port<<8) & 0xFF00) | (port>>8)})
205 if ret != 0:
206 raise MuxError("Connect failed: error %d"%ret)
207 self.proto.connected = True
208 return self.socket.sock
209 def close(self):
210 self.socket.sock.close()
211
212class USBMux(object):
213 def __init__(self, socketpath=None):
214 if socketpath is None:
215 if sys.platform == 'darwin':
216 socketpath = "/var/run/usbmuxd"
217 else:
218 socketpath = "/var/run/usbmuxd"
219 self.socketpath = socketpath
220 self.listener = MuxConnection(socketpath, BinaryProtocol)
221 try:
222 self.listener.listen()
223 self.version = 0
224 self.protoclass = BinaryProtocol
225 except MuxVersionError:
226 self.listener = MuxConnection(socketpath, PlistProtocol)
227 self.listener.listen()
228 self.protoclass = PlistProtocol
229 self.version = 1
230 self.devices = self.listener.devices
231 def process(self, timeout=None):
232 self.listener.process(timeout)
233 def connect(self, device, port):
234 connector = MuxConnection(self.socketpath, self.protoclass)
235 return connector.connect(device, port)
236
237if __name__ == "__main__":
238 mux = USBMux()
239 print "Waiting for devices..."
240 if not mux.devices:
241 mux.process(0.1)
242 while True:
243 print "Devices:"
244 for dev in mux.devices:
245 print dev
246 mux.process()
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..d2fcfef
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,14 @@
1AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir)/src $(libplist_CFLAGS) $(libusb_CFLAGS)
2AM_LDFLAGS = $(libplist_LIBS) $(libusb_LIBS)
3
4bin_PROGRAMS = usbmuxd
5
6usbmuxd_SOURCES = client.c client.h \
7 device.c device.h \
8 log.c log.h \
9 usb-linux.c usb.h \
10 utils.c utils.h \
11 main.c
12usbmuxd_CFLAGS = $(AM_CFLAGS)
13usbmuxd_LDFLAGS = $(AM_LDFLAGS)
14
diff --git a/daemon/client.c b/src/client.c
index ac1045a..ac1045a 100644
--- a/daemon/client.c
+++ b/src/client.c
diff --git a/daemon/client.h b/src/client.h
index 60d8348..60d8348 100644
--- a/daemon/client.h
+++ b/src/client.h
diff --git a/daemon/device.c b/src/device.c
index 8c786a7..8c786a7 100644
--- a/daemon/device.c
+++ b/src/device.c
diff --git a/daemon/device.h b/src/device.h
index ea77069..ea77069 100644
--- a/daemon/device.h
+++ b/src/device.h
diff --git a/daemon/log.c b/src/log.c
index 1973257..1973257 100644
--- a/daemon/log.c
+++ b/src/log.c
diff --git a/daemon/log.h b/src/log.h
index eeefa41..eeefa41 100644
--- a/daemon/log.h
+++ b/src/log.h
diff --git a/daemon/main.c b/src/main.c
index 140bee1..de5e5cc 100644
--- a/daemon/main.c
+++ b/src/main.c
@@ -435,7 +435,7 @@ int main(int argc, char *argv[])
435 /* set log level to specified verbosity */ 435 /* set log level to specified verbosity */
436 log_level = verbose; 436 log_level = verbose;
437 437
438 usbmuxd_log(LL_NOTICE, "usbmuxd v%s starting up", USBMUXD_VERSION); 438 usbmuxd_log(LL_NOTICE, "usbmuxd v%s starting up", PACKAGE_VERSION);
439 should_exit = 0; 439 should_exit = 0;
440 should_discover = 0; 440 should_discover = 0;
441 441
diff --git a/daemon/usb-linux.c b/src/usb-linux.c
index 334d967..334d967 100644
--- a/daemon/usb-linux.c
+++ b/src/usb-linux.c
diff --git a/daemon/usb.h b/src/usb.h
index 6fe7ee6..6fe7ee6 100644
--- a/daemon/usb.h
+++ b/src/usb.h
diff --git a/common/utils.c b/src/utils.c
index 0096907..ceef535 100644
--- a/common/utils.c
+++ b/src/utils.c
@@ -29,14 +29,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29#include <stdio.h> 29#include <stdio.h>
30#include "utils.h" 30#include "utils.h"
31 31
32#ifdef USBMUXD_DAEMON 32#include "log.h"
33# include "log.h" 33#define util_error(...) usbmuxd_log(LL_ERROR, __VA_ARGS__)
34# define util_error(...) usbmuxd_log(LL_ERROR, __VA_ARGS__)
35#else
36# define util_error(...) fprintf(stderr, __VA_ARGS__)
37#endif
38 34
39#ifdef USBMUXD_DAEMON
40void fdlist_create(struct fdlist *list) 35void fdlist_create(struct fdlist *list)
41{ 36{
42 list->count = 0; 37 list->count = 0;
@@ -72,7 +67,6 @@ void fdlist_reset(struct fdlist *list)
72{ 67{
73 list->count = 0; 68 list->count = 0;
74} 69}
75#endif
76 70
77void collection_init(struct collection *col) 71void collection_init(struct collection *col)
78{ 72{
diff --git a/common/utils.h b/src/utils.h
index 0addb46..5aa2915 100644
--- a/common/utils.h
+++ b/src/utils.h
@@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23#ifndef __UTILS_H__ 23#ifndef __UTILS_H__
24#define __UTILS_H__ 24#define __UTILS_H__
25 25
26#ifdef USBMUXD_DAEMON
27#include <poll.h> 26#include <poll.h>
28 27
29enum fdowner { 28enum fdowner {
@@ -43,7 +42,6 @@ void fdlist_create(struct fdlist *list);
43void fdlist_add(struct fdlist *list, enum fdowner owner, int fd, short events); 42void fdlist_add(struct fdlist *list, enum fdowner owner, int fd, short events);
44void fdlist_free(struct fdlist *list); 43void fdlist_free(struct fdlist *list);
45void fdlist_reset(struct fdlist *list); 44void fdlist_reset(struct fdlist *list);
46#endif
47 45
48struct collection { 46struct collection {
49 void **list; 47 void **list;
diff --git a/stuff/README b/stuff/README
deleted file mode 100644
index 290285d..0000000
--- a/stuff/README
+++ /dev/null
@@ -1,25 +0,0 @@
1*** NOTE:
2*** Doing this is mostly obsolete. The preferred method to sync music to an
3*** iPhone now is to use ifuse or some other afc-based client, which does not
4*** require jailbreaking or adding this service. Please take a look at the
5*** libiphone, ifuse, and libgpod projects.
6
7com.openssh.sft.plist is a launchd configuration to set up a bare SFTP server
8on TCP port 2299 localhost-only for USB use. It's nice for relatively fast music
9syncing and file transfer under Linux (and it avoids encryption). Con: it gives
10anyone with usb access root FS access on the phone, as well as anything running
11on the phone itself.
12
13Use it with a command like this:
14
15IPATH=/var/mobile/Media
16MOUNTPOINT=$HOME/media/iphone
17$ sshfs localhost:$IPATH $MOUNTPOINT -o workaround=rename -o directport=2299 \
18 -o kernel_cache -o entry_timeout=30 -o attr_timeout=30
19
20Make sure you run tcprelay.py:
21$ python tcprelay.py -t 2299
22
23Remember that to bypass the stupid new iTunesDB hash you need to edit
24/System/Library/Lockdown/Checkpoint.xml and change DBVersion to 2.
25
diff --git a/stuff/com.openssh.sftp.plist b/stuff/com.openssh.sftp.plist
deleted file mode 100644
index 569fabc..0000000
--- a/stuff/com.openssh.sftp.plist
+++ /dev/null
@@ -1,41 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4
5<dict>
6 <key>Label</key>
7 <string>com.openssh.sftpd</string>
8
9 <key>Program</key>
10 <string>/usr/libexec/sftp-server</string>
11
12 <key>ProgramArguments</key>
13 <array>
14 <string>/usr/libexec/sftp-server</string>
15 </array>
16
17 <key>SessionCreate</key>
18 <true/>
19
20 <key>Sockets</key>
21 <dict>
22 <key>Listeners</key>
23 <dict>
24 <key>SockServiceName</key>
25 <string>2299</string>
26 <key>SockNodeName</key>
27 <string>127.0.0.1</string>
28 </dict>
29 </dict>
30
31 <key>StandardErrorPath</key>
32 <string>/dev/null</string>
33
34 <key>inetdCompatibility</key>
35 <dict>
36 <key>Wait</key>
37 <false/>
38 </dict>
39</dict>
40
41</plist>
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
deleted file mode 100644
index 64d0d0e..0000000
--- a/tools/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
1include_directories (${CMAKE_SOURCE_DIR}/libusbmuxd)
2link_directories (${CMAKE_BINARY_DIR}/libusbmuxd)
3
4add_executable(iproxy iproxy.c)
5if(WIN32)
6 target_link_libraries(iproxy libusbmuxd pthread ws2_32)
7else()
8 target_link_libraries(iproxy libusbmuxd pthread)
9endif()
10
11install(TARGETS iproxy RUNTIME DESTINATION bin)
diff --git a/tools/iproxy.c b/tools/iproxy.c
deleted file mode 100644
index e4e39f6..0000000
--- a/tools/iproxy.c
+++ /dev/null
@@ -1,281 +0,0 @@
1/*
2 iproxy -- proxy that enables tcp service access to iPhone/iPod
3
4Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
5Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
6
7Based upon iTunnel source code, Copyright (c) 2008 Jing Su.
8http://www.cs.toronto.edu/~jingsu/itunnel/
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
24TODO: improve code...
25
26*/
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <fcntl.h>
32#include <stddef.h>
33#include <unistd.h>
34#include <errno.h>
35#ifdef WIN32
36#include <windows.h>
37#include <winsock2.h>
38typedef unsigned int socklen_t;
39#else
40#include <sys/socket.h>
41#include <sys/un.h>
42#include <arpa/inet.h>
43#include <pthread.h>
44#include <netinet/in.h>
45#endif
46#include "sock_stuff.h"
47#include "usbmuxd.h"
48
49static uint16_t listen_port = 0;
50static uint16_t device_port = 0;
51
52struct client_data {
53 int fd;
54 int sfd;
55 volatile int stop_ctos;
56 volatile int stop_stoc;
57};
58
59void *run_stoc_loop(void *arg)
60{
61 struct client_data *cdata = (struct client_data*)arg;
62 int recv_len;
63 int sent;
64 char buffer[131072];
65
66 printf("%s: fd = %d\n", __func__, cdata->fd);
67
68 while (!cdata->stop_stoc && cdata->fd>0 && cdata->sfd>0) {
69 recv_len = recv_buf_timeout(cdata->sfd, buffer, sizeof(buffer), 0, 5000);
70 if (recv_len <= 0) {
71 if (recv_len == 0) {
72 // try again
73 continue;
74 } else {
75 fprintf(stderr, "recv failed: %s\n", strerror(errno));
76 break;
77 }
78 } else {
79// printf("received %d bytes from server\n", recv_len);
80 // send to socket
81 sent = send_buf(cdata->fd, buffer, recv_len);
82 if (sent < recv_len) {
83 if (sent <= 0) {
84 fprintf(stderr, "send failed: %s\n", strerror(errno));
85 break;
86 } else {
87 fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len);
88 }
89 } else {
90 // sending succeeded, receive from device
91// printf("pushed %d bytes to client\n", sent);
92 }
93 }
94 }
95 close(cdata->fd);
96 cdata->fd = -1;
97 cdata->stop_ctos = 1;
98
99 return NULL;
100}
101
102void *run_ctos_loop(void *arg)
103{
104 struct client_data *cdata = (struct client_data*)arg;
105 int recv_len;
106 int sent;
107 char buffer[131072];
108#ifdef WIN32
109 HANDLE stoc = NULL;
110#else
111 pthread_t stoc;
112#endif
113
114 printf("%s: fd = %d\n", __func__, cdata->fd);
115
116 cdata->stop_stoc = 0;
117#ifdef WIN32
118 stoc = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)run_stoc_loop, cdata, 0, NULL);
119#else
120 pthread_create(&stoc, NULL, run_stoc_loop, cdata);
121#endif
122
123 while (!cdata->stop_ctos && cdata->fd>0 && cdata->sfd>0) {
124 recv_len = recv_buf_timeout(cdata->fd, buffer, sizeof(buffer), 0, 5000);
125 if (recv_len <= 0) {
126 if (recv_len == 0) {
127 // try again
128 continue;
129 } else {
130 fprintf(stderr, "recv failed: %s\n", strerror(errno));
131 break;
132 }
133 } else {
134// printf("pulled %d bytes from client\n", recv_len);
135 // send to local socket
136 sent = send_buf(cdata->sfd, buffer, recv_len);
137 if (sent < recv_len) {
138 if (sent <= 0) {
139 fprintf(stderr, "send failed: %s\n", strerror(errno));
140 break;
141 } else {
142 fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len);
143 }
144 } else {
145 // sending succeeded, receive from device
146// printf("sent %d bytes to server\n", sent);
147 }
148 }
149 }
150 close(cdata->fd);
151 cdata->fd = -1;
152 cdata->stop_stoc = 1;
153
154#ifdef WIN32
155 WaitForSingleObject(stoc, INFINITE);
156#else
157 pthread_join(stoc, NULL);
158#endif
159
160 return NULL;
161}
162
163void *acceptor_thread(void *arg)
164{
165 struct client_data *cdata;
166 usbmuxd_device_info_t *dev_list = NULL;
167#ifdef WIN32
168 HANDLE ctos = NULL;
169#else
170 pthread_t ctos;
171#endif
172 int count;
173
174 if (!arg) {
175 fprintf(stderr, "invalid client_data provided!\n");
176 return NULL;
177 }
178
179 cdata = (struct client_data*)arg;
180
181 if ((count = usbmuxd_get_device_list(&dev_list)) < 0) {
182 printf("Connecting to usbmuxd failed, terminating.\n");
183 free(dev_list);
184 return NULL;
185 }
186
187 fprintf(stdout, "Number of available devices == %d\n", count);
188
189 if (dev_list == NULL || dev_list[0].handle == 0) {
190 printf("No connected device found, terminating.\n");
191 free(dev_list);
192 return NULL;
193 }
194
195 fprintf(stdout, "Requesting connecion to device handle == %d (serial: %s), port %d\n", dev_list[0].handle, dev_list[0].udid, device_port);
196
197 cdata->sfd = usbmuxd_connect(dev_list[0].handle, device_port);
198 free(dev_list);
199 if (cdata->sfd < 0) {
200 fprintf(stderr, "Error connecting to device!\n");
201 } else {
202 cdata->stop_ctos = 0;
203#ifdef WIN32
204 ctos = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)run_ctos_loop, cdata, 0, NULL);
205 WaitForSingleObject(ctos, INFINITE);
206#else
207 pthread_create(&ctos, NULL, run_ctos_loop, cdata);
208 pthread_join(ctos, NULL);
209#endif
210 }
211
212 if (cdata->fd > 0) {
213 close(cdata->fd);
214 }
215 if (cdata->sfd > 0) {
216 close(cdata->sfd);
217 }
218
219 return NULL;
220}
221
222int main(int argc, char **argv)
223{
224 int mysock = -1;
225
226 if (argc != 3) {
227 printf("usage: %s LOCAL_TCP_PORT DEVICE_TCP_PORT\n", argv[0]);
228 return 0;
229 }
230
231 listen_port = atoi(argv[1]);
232 device_port = atoi(argv[2]);
233
234 if (!listen_port) {
235 fprintf(stderr, "Invalid listen_port specified!\n");
236 return -EINVAL;
237 }
238
239 if (!device_port) {
240 fprintf(stderr, "Invalid device_port specified!\n");
241 return -EINVAL;
242 }
243
244 // first create the listening socket endpoint waiting for connections.
245 mysock = create_socket(listen_port);
246 if (mysock < 0) {
247 fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
248 return -errno;
249 } else {
250#ifdef WIN32
251 HANDLE acceptor = NULL;
252#else
253 pthread_t acceptor;
254#endif
255 struct sockaddr_in c_addr;
256 socklen_t len = sizeof(struct sockaddr_in);
257 struct client_data cdata;
258 int c_sock;
259 while (1) {
260 printf("waiting for connection\n");
261 c_sock = accept(mysock, (struct sockaddr*)&c_addr, &len);
262 if (c_sock) {
263 printf("accepted connection, fd = %d\n", c_sock);
264 cdata.fd = c_sock;
265#ifdef WIN32
266 acceptor = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)acceptor_thread, &cdata, 0, NULL);
267 WaitForSingleObject(acceptor, INFINITE);
268#else
269 pthread_create(&acceptor, NULL, acceptor_thread, &cdata);
270 pthread_join(acceptor, NULL);
271#endif
272 } else {
273 break;
274 }
275 }
276 close(c_sock);
277 close(mysock);
278 }
279
280 return 0;
281}
diff --git a/udev/85-usbmuxd.rules.in b/udev/85-usbmuxd.rules.in
index 6f2186b..da8042d 100644
--- a/udev/85-usbmuxd.rules.in
+++ b/udev/85-usbmuxd.rules.in
@@ -1,7 +1,7 @@
1# usbmuxd ("Apple Mobile Device" muxer listening on /var/run/usbmuxd) 1# usbmuxd ("Apple Mobile Device" muxer listening on /var/run/usbmuxd)
2 2
3# Forces iDevices to the last USB configuration and runs usbmuxd 3# Forces iDevices to the last USB configuration and runs usbmuxd
4ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="12[9a][0-9a-f]", ENV{USBMUX_SUPPORTED}="1", ATTR{bConfigurationValue}!="$attr{bNumConfigurations}", ATTR{bConfigurationValue}="$attr{bNumConfigurations}", OWNER="usbmux", RUN+="@CMAKE_INSTALL_PREFIX@/sbin/usbmuxd -u -U usbmux" 4ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="12[9a][0-9a-f]", ENV{USBMUX_SUPPORTED}="1", ATTR{bConfigurationValue}!="$attr{bNumConfigurations}", ATTR{bConfigurationValue}="$attr{bNumConfigurations}", OWNER="usbmux", RUN+="@prefix@/sbin/usbmuxd -u -U usbmux"
5 5
6# Exit usbmuxd when the last device is removed 6# Exit usbmuxd when the last device is removed
7ACTION=="remove", SUBSYSTEM=="usb", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*", ENV{INTERFACE}=="255/*", RUN+="@CMAKE_INSTALL_PREFIX@/sbin/usbmuxd -x" 7ACTION=="remove", SUBSYSTEM=="usb", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*", ENV{INTERFACE}=="255/*", RUN+="@prefix@/sbin/usbmuxd -x"
diff --git a/udev/CMakeLists.txt b/udev/CMakeLists.txt
deleted file mode 100644
index 0f7042d..0000000
--- a/udev/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
1CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/85-usbmuxd.rules.in ${CMAKE_CURRENT_BINARY_DIR}/85-usbmuxd.rules @ONLY)
2install(FILES ${CMAKE_CURRENT_BINARY_DIR}/85-usbmuxd.rules DESTINATION /lib/udev/rules.d/)