summaryrefslogtreecommitdiff
path: root/src/extras/gudev
diff options
context:
space:
mode:
Diffstat (limited to 'src/extras/gudev')
-rw-r--r--src/extras/gudev/.gitignore9
-rw-r--r--src/extras/gudev/COPYING502
-rw-r--r--src/extras/gudev/docs/.gitignore16
-rw-r--r--src/extras/gudev/docs/Makefile.am106
-rw-r--r--src/extras/gudev/docs/gudev-docs.xml93
-rw-r--r--src/extras/gudev/docs/gudev-sections.txt113
-rw-r--r--src/extras/gudev/docs/gudev.types4
-rw-r--r--src/extras/gudev/docs/version.xml.in1
-rwxr-xr-xsrc/extras/gudev/gjs-example.js75
-rw-r--r--src/extras/gudev/gudev-1.0.pc.in11
-rw-r--r--src/extras/gudev/gudev.h33
-rw-r--r--src/extras/gudev/gudevclient.c527
-rw-r--r--src/extras/gudev/gudevclient.h100
-rw-r--r--src/extras/gudev/gudevdevice.c963
-rw-r--r--src/extras/gudev/gudevdevice.h128
-rw-r--r--src/extras/gudev/gudevenumerator.c431
-rw-r--r--src/extras/gudev/gudevenumerator.h107
-rw-r--r--src/extras/gudev/gudevenums.h49
-rw-r--r--src/extras/gudev/gudevenumtypes.c.template39
-rw-r--r--src/extras/gudev/gudevenumtypes.h.template24
-rw-r--r--src/extras/gudev/gudevmarshal.list1
-rw-r--r--src/extras/gudev/gudevprivate.h41
-rw-r--r--src/extras/gudev/gudevtypes.h51
-rwxr-xr-xsrc/extras/gudev/seed-example-enum.js38
-rwxr-xr-xsrc/extras/gudev/seed-example.js72
25 files changed, 3534 insertions, 0 deletions
diff --git a/src/extras/gudev/.gitignore b/src/extras/gudev/.gitignore
new file mode 100644
index 0000000000..d20fa523e4
--- /dev/null
+++ b/src/extras/gudev/.gitignore
@@ -0,0 +1,9 @@
+gtk-doc.make
+docs/version.xml
+gudev-1.0.pc
+gudevenumtypes.c
+gudevenumtypes.h
+gudevmarshal.c
+gudevmarshal.h
+GUdev-1.0.gir
+GUdev-1.0.typelib
diff --git a/src/extras/gudev/COPYING b/src/extras/gudev/COPYING
new file mode 100644
index 0000000000..47044a8c58
--- /dev/null
+++ b/src/extras/gudev/COPYING
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/src/extras/gudev/docs/.gitignore b/src/extras/gudev/docs/.gitignore
new file mode 100644
index 0000000000..8eada6d409
--- /dev/null
+++ b/src/extras/gudev/docs/.gitignore
@@ -0,0 +1,16 @@
+gudev-overrides.txt
+gudev-decl-list.txt
+gudev-decl.txt
+gudev-undeclared.txt
+gudev-undocumented.txt
+gudev-unused.txt
+gudev.args
+gudev.hierarchy
+gudev.interfaces
+gudev.prerequisites
+gudev.signals
+html.stamp
+html/*
+xml/*
+tmpl/*
+*.stamp
diff --git a/src/extras/gudev/docs/Makefile.am b/src/extras/gudev/docs/Makefile.am
new file mode 100644
index 0000000000..d03fc65127
--- /dev/null
+++ b/src/extras/gudev/docs/Makefile.am
@@ -0,0 +1,106 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.10 at least.
+AUTOMAKE_OPTIONS = 1.10
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=gudev
+
+# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
+#DOC_MODULE_VERSION=2
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=..
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=g_udev
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir)
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/src/extras/gudev/*.h
+CFILE_GLOB=$(top_srcdir)/src/extras/gudev/*.c
+
+# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
+# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
+EXTRA_HFILES=
+
+# Header files to ignore when scanning. Use base file name, no paths
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files = version.xml
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+GTKDOC_CFLAGS = \
+ $(DBUS_GLIB_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ -I$(top_srcdir)/src/extras/gudev \
+ -I$(top_builddir)/src/extras/gudev
+
+GTKDOC_LIBS = \
+ $(GLIB_LIBS) \
+ $(top_builddir)/src/extras/gudev/libgudev-1.0.la
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
+#DISTCLEANFILES +=
+
+# Comment this out if you want your docs-status tested during 'make check'
+if ENABLE_GTK_DOC
+#TESTS_ENVIRONMENT = cd $(srcsrc)
+#TESTS = $(GTKDOC_CHECK)
+endif
diff --git a/src/extras/gudev/docs/gudev-docs.xml b/src/extras/gudev/docs/gudev-docs.xml
new file mode 100644
index 0000000000..65fdfff8e5
--- /dev/null
+++ b/src/extras/gudev/docs/gudev-docs.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>GUDev Reference Manual</title>
+ <releaseinfo>For GUdev version &version;</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>David</firstname>
+ <surname>Zeuthen</surname>
+ <affiliation>
+ <address>
+ <email>davidz@redhat.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Bastien</firstname>
+ <surname>Nocera</surname>
+ <affiliation>
+ <address>
+ <email>hadess@hadess.net</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2011</year>
+ <holder>The GUDev Authors</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the <citetitle>GNU Free
+ Documentation License</citetitle>, Version 1.1 or any later
+ version published by the Free Software Foundation with no
+ Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. You may obtain a copy of the <citetitle>GNU Free
+ Documentation License</citetitle> from the Free Software
+ Foundation by visiting <ulink type="http"
+ url="http://www.fsf.org">their Web site</ulink> or by writing
+ to:
+
+ <address>
+ The Free Software Foundation, Inc.,
+ <street>59 Temple Place</street> - Suite 330,
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>,
+ <country>USA</country>
+ </address>
+ </para>
+
+ <para>
+ Many of the names used by companies to distinguish their
+ products and services are claimed as trademarks. Where those
+ names appear in any freedesktop.org documentation, and those
+ trademarks are made aware to the members of the
+ freedesktop.org Project, the names have been printed in caps
+ or initial caps.
+ </para>
+ </legalnotice>
+ </bookinfo>
+
+ <reference id="ref-API">
+ <title>API Reference</title>
+ <partintro>
+ <para>
+ This part presents the class and function reference for the
+ <literal>libgudev</literal> library.
+ </para>
+ </partintro>
+ <xi:include href="xml/gudevclient.xml"/>
+ <xi:include href="xml/gudevdevice.xml"/>
+ <xi:include href="xml/gudevenumerator.xml"/>
+ </reference>
+
+ <chapter id="gudev-hierarchy">
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+ <index>
+ <title>Index</title>
+ </index>
+ <index role="165">
+ <title>Index of new symbols in 165</title>
+ <xi:include href="xml/api-index-165.xml"><xi:fallback /></xi:include>
+ </index>
+
+</book>
diff --git a/src/extras/gudev/docs/gudev-sections.txt b/src/extras/gudev/docs/gudev-sections.txt
new file mode 100644
index 0000000000..213e1a7465
--- /dev/null
+++ b/src/extras/gudev/docs/gudev-sections.txt
@@ -0,0 +1,113 @@
+<SECTION>
+<FILE>gudevclient</FILE>
+<TITLE>GUdevClient</TITLE>
+GUdevClient
+GUdevClientClass
+GUdevDeviceType
+GUdevDeviceNumber
+g_udev_client_new
+g_udev_client_query_by_subsystem
+g_udev_client_query_by_device_number
+g_udev_client_query_by_device_file
+g_udev_client_query_by_sysfs_path
+g_udev_client_query_by_subsystem_and_name
+<SUBSECTION Standard>
+G_UDEV_CLIENT
+G_UDEV_IS_CLIENT
+G_UDEV_TYPE_CLIENT
+g_udev_client_get_type
+G_UDEV_CLIENT_CLASS
+G_UDEV_IS_CLIENT_CLASS
+G_UDEV_CLIENT_GET_CLASS
+<SUBSECTION Private>
+GUdevClientPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevdevice</FILE>
+<TITLE>GUdevDevice</TITLE>
+GUdevDevice
+GUdevDeviceClass
+g_udev_device_get_subsystem
+g_udev_device_get_devtype
+g_udev_device_get_name
+g_udev_device_get_number
+g_udev_device_get_sysfs_path
+g_udev_device_get_driver
+g_udev_device_get_action
+g_udev_device_get_seqnum
+g_udev_device_get_device_type
+g_udev_device_get_device_number
+g_udev_device_get_device_file
+g_udev_device_get_device_file_symlinks
+g_udev_device_get_parent
+g_udev_device_get_parent_with_subsystem
+g_udev_device_get_tags
+g_udev_device_get_is_initialized
+g_udev_device_get_usec_since_initialized
+g_udev_device_get_property_keys
+g_udev_device_has_property
+g_udev_device_get_property
+g_udev_device_get_property_as_int
+g_udev_device_get_property_as_uint64
+g_udev_device_get_property_as_double
+g_udev_device_get_property_as_boolean
+g_udev_device_get_property_as_strv
+g_udev_device_get_sysfs_attr
+g_udev_device_get_sysfs_attr_as_int
+g_udev_device_get_sysfs_attr_as_uint64
+g_udev_device_get_sysfs_attr_as_double
+g_udev_device_get_sysfs_attr_as_boolean
+g_udev_device_get_sysfs_attr_as_strv
+<SUBSECTION Standard>
+G_UDEV_DEVICE
+G_UDEV_IS_DEVICE
+G_UDEV_TYPE_DEVICE
+g_udev_device_get_type
+G_UDEV_DEVICE_CLASS
+G_UDEV_IS_DEVICE_CLASS
+G_UDEV_DEVICE_GET_CLASS
+<SUBSECTION Private>
+GUdevDevicePrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevenumerator</FILE>
+<TITLE>GUdevEnumerator</TITLE>
+GUdevEnumerator
+GUdevEnumeratorClass
+g_udev_enumerator_new
+g_udev_enumerator_add_match_subsystem
+g_udev_enumerator_add_nomatch_subsystem
+g_udev_enumerator_add_match_sysfs_attr
+g_udev_enumerator_add_nomatch_sysfs_attr
+g_udev_enumerator_add_match_property
+g_udev_enumerator_add_match_name
+g_udev_enumerator_add_match_tag
+g_udev_enumerator_add_match_is_initialized
+g_udev_enumerator_add_sysfs_path
+g_udev_enumerator_execute
+<SUBSECTION Standard>
+G_UDEV_ENUMERATOR
+G_UDEV_IS_ENUMERATOR
+G_UDEV_TYPE_ENUMERATOR
+g_udev_enumerator_get_type
+G_UDEV_ENUMERATOR_CLASS
+G_UDEV_IS_ENUMERATOR_CLASS
+G_UDEV_ENUMERATOR_GET_CLASS
+<SUBSECTION Private>
+GUdevEnumeratorPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevmarshal</FILE>
+<SUBSECTION Private>
+g_udev_marshal_VOID__STRING_OBJECT
+</SECTION>
+
+<SECTION>
+<FILE>gudevenumtypes</FILE>
+<SUBSECTION Private>
+G_TYPE_UDEV_DEVICE_TYPE
+g_udev_device_type_get_type
+</SECTION>
diff --git a/src/extras/gudev/docs/gudev.types b/src/extras/gudev/docs/gudev.types
new file mode 100644
index 0000000000..a89857a04d
--- /dev/null
+++ b/src/extras/gudev/docs/gudev.types
@@ -0,0 +1,4 @@
+g_udev_device_type_get_type
+g_udev_device_get_type
+g_udev_client_get_type
+g_udev_enumerator_get_type
diff --git a/src/extras/gudev/docs/version.xml.in b/src/extras/gudev/docs/version.xml.in
new file mode 100644
index 0000000000..d78bda9342
--- /dev/null
+++ b/src/extras/gudev/docs/version.xml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/src/extras/gudev/gjs-example.js b/src/extras/gudev/gjs-example.js
new file mode 100755
index 0000000000..5586fd6a61
--- /dev/null
+++ b/src/extras/gudev/gjs-example.js
@@ -0,0 +1,75 @@
+#!/usr/bin/env gjs-console
+
+// This currently depends on the following patches to gjs
+//
+// http://bugzilla.gnome.org/show_bug.cgi?id=584558
+// http://bugzilla.gnome.org/show_bug.cgi?id=584560
+// http://bugzilla.gnome.org/show_bug.cgi?id=584568
+
+const GUdev = imports.gi.GUdev;
+const Mainloop = imports.mainloop;
+
+function print_device (device) {
+ print (" subsystem: " + device.get_subsystem ());
+ print (" devtype: " + device.get_devtype ());
+ print (" name: " + device.get_name ());
+ print (" number: " + device.get_number ());
+ print (" sysfs_path: " + device.get_sysfs_path ());
+ print (" driver: " + device.get_driver ());
+ print (" action: " + device.get_action ());
+ print (" seqnum: " + device.get_seqnum ());
+ print (" device type: " + device.get_device_type ());
+ print (" device number: " + device.get_device_number ());
+ print (" device file: " + device.get_device_file ());
+ print (" device file symlinks: " + device.get_device_file_symlinks ());
+ print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
+ var keys = device.get_property_keys ();
+ for (var n = 0; n < keys.length; n++) {
+ print (" " + keys[n] + "=" + device.get_property (keys[n]));
+ }
+}
+
+function on_uevent (client, action, device) {
+ print ("action " + action + " on device " + device.get_sysfs_path());
+ print_device (device);
+ print ("");
+}
+
+var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
+client.connect ("uevent", on_uevent);
+
+var block_devices = client.query_by_subsystem ("block");
+for (var n = 0; n < block_devices.length; n++) {
+ print ("block device: " + block_devices[n].get_device_file ());
+}
+
+var d;
+
+d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
+if (d == null) {
+ print ("query_by_device_number 0x810 -> null");
+} else {
+ print ("query_by_device_number 0x810 -> " + d.get_device_file ());
+ var dd = d.get_parent_with_subsystem ("usb", null);
+ print_device (dd);
+ print ("--------------------------------------------------------------------------");
+ while (d != null) {
+ print_device (d);
+ print ("");
+ d = d.get_parent ();
+ }
+}
+
+d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
+print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
+
+d = client.query_by_subsystem_and_name ("block", "sda2");
+print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/sda");
+print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/block/8:0");
+print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
+
+Mainloop.run('udev-example');
diff --git a/src/extras/gudev/gudev-1.0.pc.in b/src/extras/gudev/gudev-1.0.pc.in
new file mode 100644
index 0000000000..058262d767
--- /dev/null
+++ b/src/extras/gudev/gudev-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gudev-1.0
+Description: GObject bindings for libudev
+Version: @VERSION@
+Requires: glib-2.0, gobject-2.0
+Libs: -L${libdir} -lgudev-1.0
+Cflags: -I${includedir}/gudev-1.0
diff --git a/src/extras/gudev/gudev.h b/src/extras/gudev/gudev.h
new file mode 100644
index 0000000000..a313460817
--- /dev/null
+++ b/src/extras/gudev/gudev.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_UDEV_H__
+#define __G_UDEV_H__
+
+#define _GUDEV_INSIDE_GUDEV_H 1
+#include <gudev/gudevenums.h>
+#include <gudev/gudevenumtypes.h>
+#include <gudev/gudevtypes.h>
+#include <gudev/gudevclient.h>
+#include <gudev/gudevdevice.h>
+#include <gudev/gudevenumerator.h>
+#undef _GUDEV_INSIDE_GUDEV_H
+
+#endif /* __G_UDEV_H__ */
diff --git a/src/extras/gudev/gudevclient.c b/src/extras/gudev/gudevclient.c
new file mode 100644
index 0000000000..a6465ad943
--- /dev/null
+++ b/src/extras/gudev/gudevclient.c
@@ -0,0 +1,527 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevclient.h"
+#include "gudevdevice.h"
+#include "gudevmarshal.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevclient
+ * @short_description: Query devices and listen to uevents
+ *
+ * #GUdevClient is used to query information about devices on a Linux
+ * system from the Linux kernel and the udev device
+ * manager.
+ *
+ * Device information is retrieved from the kernel (through the
+ * <literal>sysfs</literal> filesystem) and the udev daemon (through a
+ * <literal>tmpfs</literal> filesystem) and presented through
+ * #GUdevDevice objects. This means that no blocking IO ever happens
+ * (in both cases, we are essentially just reading data from kernel
+ * memory) and as such there are no asynchronous versions of the
+ * provided methods.
+ *
+ * To get #GUdevDevice objects, use
+ * g_udev_client_query_by_subsystem(),
+ * g_udev_client_query_by_device_number(),
+ * g_udev_client_query_by_device_file(),
+ * g_udev_client_query_by_sysfs_path(),
+ * g_udev_client_query_by_subsystem_and_name()
+ * or the #GUdevEnumerator type.
+ *
+ * To listen to uevents, connect to the #GUdevClient::uevent signal.
+ */
+
+struct _GUdevClientPrivate
+{
+ GSource *watch_source;
+ struct udev *udev;
+ struct udev_monitor *monitor;
+
+ gchar **subsystems;
+};
+
+enum
+{
+ PROP_0,
+ PROP_SUBSYSTEMS,
+};
+
+enum
+{
+ UEVENT_SIGNAL,
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+monitor_event (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ GUdevClient *client = (GUdevClient *) data;
+ GUdevDevice *device;
+ struct udev_device *udevice;
+
+ if (client->priv->monitor == NULL)
+ goto out;
+ udevice = udev_monitor_receive_device (client->priv->monitor);
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+ g_signal_emit (client,
+ signals[UEVENT_SIGNAL],
+ 0,
+ g_udev_device_get_action (device),
+ device);
+ g_object_unref (device);
+
+ out:
+ return TRUE;
+}
+
+static void
+g_udev_client_finalize (GObject *object)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+
+ if (client->priv->watch_source != NULL)
+ {
+ g_source_destroy (client->priv->watch_source);
+ client->priv->watch_source = NULL;
+ }
+
+ if (client->priv->monitor != NULL)
+ {
+ udev_monitor_unref (client->priv->monitor);
+ client->priv->monitor = NULL;
+ }
+
+ if (client->priv->udev != NULL)
+ {
+ udev_unref (client->priv->udev);
+ client->priv->udev = NULL;
+ }
+
+ g_strfreev (client->priv->subsystems);
+
+ if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object);
+}
+
+static void
+g_udev_client_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_SUBSYSTEMS:
+ if (client->priv->subsystems != NULL)
+ g_strfreev (client->priv->subsystems);
+ client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_client_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_SUBSYSTEMS:
+ g_value_set_boxed (value, client->priv->subsystems);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_client_constructed (GObject *object)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+ GIOChannel *channel;
+ guint n;
+
+ client->priv->udev = udev_new ();
+
+ /* connect to event source */
+ client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");
+
+ //g_debug ("ss = %p", client->priv->subsystems);
+
+ if (client->priv->subsystems != NULL)
+ {
+ /* install subsystem filters to only wake up for certain events */
+ for (n = 0; client->priv->subsystems[n] != NULL; n++)
+ {
+ gchar *subsystem;
+ gchar *devtype;
+ gchar *s;
+
+ subsystem = g_strdup (client->priv->subsystems[n]);
+ devtype = NULL;
+
+ //g_debug ("s = '%s'", subsystem);
+
+ s = strstr (subsystem, "/");
+ if (s != NULL)
+ {
+ devtype = s + 1;
+ *s = '\0';
+ }
+
+ if (client->priv->monitor != NULL)
+ udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
+
+ g_free (subsystem);
+ }
+
+ /* listen to events, and buffer them */
+ if (client->priv->monitor != NULL)
+ {
+ udev_monitor_enable_receiving (client->priv->monitor);
+ channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
+ client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
+ g_io_channel_unref (channel);
+ g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
+ g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
+ g_source_unref (client->priv->watch_source);
+ }
+ else
+ {
+ client->priv->watch_source = NULL;
+ }
+ }
+
+ if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
+}
+
+
+static void
+g_udev_client_class_init (GUdevClientClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->constructed = g_udev_client_constructed;
+ gobject_class->set_property = g_udev_client_set_property;
+ gobject_class->get_property = g_udev_client_get_property;
+ gobject_class->finalize = g_udev_client_finalize;
+
+ /**
+ * GUdevClient:subsystems:
+ *
+ * The subsystems to listen for uevents on.
+ *
+ * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
+ * "subsystem/devtype". For example, to only listen for uevents
+ * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
+ * "usb/usb_interface".
+ *
+ * If this property is %NULL, then no events will be reported. If
+ * it's the empty array, events from all subsystems will be
+ * reported.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SUBSYSTEMS,
+ g_param_spec_boxed ("subsystems",
+ "The subsystems to listen for changes on",
+ "The subsystems to listen for changes on",
+ G_TYPE_STRV,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE));
+
+ /**
+ * GUdevClient::uevent:
+ * @client: The #GUdevClient receiving the event.
+ * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
+ * @device: Details about the #GUdevDevice the event is for.
+ *
+ * Emitted when @client receives an uevent.
+ *
+ * This signal is emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that @client was created in.
+ */
+ signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GUdevClientClass, uevent),
+ NULL,
+ NULL,
+ g_udev_marshal_VOID__STRING_OBJECT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_STRING,
+ G_UDEV_TYPE_DEVICE);
+
+ g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
+}
+
+static void
+g_udev_client_init (GUdevClient *client)
+{
+ client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
+ G_UDEV_TYPE_CLIENT,
+ GUdevClientPrivate);
+}
+
+/**
+ * g_udev_client_new:
+ * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
+ *
+ * Constructs a #GUdevClient object that can be used to query
+ * information about devices. Connect to the #GUdevClient::uevent
+ * signal to listen for uevents. Note that signals are emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that you call this constructor from.
+ *
+ * Returns: A new #GUdevClient object. Free with g_object_unref().
+ */
+GUdevClient *
+g_udev_client_new (const gchar * const *subsystems)
+{
+ return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
+}
+
+/**
+ * g_udev_client_query_by_subsystem:
+ * @client: A #GUdevClient.
+ * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
+ *
+ * Gets all devices belonging to @subsystem.
+ *
+ * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
+ */
+GList *
+g_udev_client_query_by_subsystem (GUdevClient *client,
+ const gchar *subsystem)
+{
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *l, *devices;
+ GList *ret;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+
+ ret = NULL;
+
+ /* prepare a device scan */
+ enumerate = udev_enumerate_new (client->priv->udev);
+
+ /* filter for subsystem */
+ if (subsystem != NULL)
+ udev_enumerate_add_match_subsystem (enumerate, subsystem);
+ /* retrieve the list */
+ udev_enumerate_scan_devices (enumerate);
+
+ /* add devices to the list */
+ devices = udev_enumerate_get_list_entry (enumerate);
+ for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
+ {
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
+ udev_list_entry_get_name (l));
+ if (udevice == NULL)
+ continue;
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+ ret = g_list_prepend (ret, device);
+ }
+ udev_enumerate_unref (enumerate);
+
+ ret = g_list_reverse (ret);
+
+ return ret;
+}
+
+/**
+ * g_udev_client_query_by_device_number:
+ * @client: A #GUdevClient.
+ * @type: A value from the #GUdevDeviceType enumeration.
+ * @number: A device number.
+ *
+ * Looks up a device for a type and device number.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_device_number (GUdevClient *client,
+ GUdevDeviceType type,
+ GUdevDeviceNumber number)
+{
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+
+ device = NULL;
+ udevice = udev_device_new_from_devnum (client->priv->udev, type, number);
+
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+
+ out:
+ return device;
+}
+
+/**
+ * g_udev_client_query_by_device_file:
+ * @client: A #GUdevClient.
+ * @device_file: A device file.
+ *
+ * Looks up a device for a device file.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_device_file (GUdevClient *client,
+ const gchar *device_file)
+{
+ struct stat stat_buf;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (device_file != NULL, NULL);
+
+ device = NULL;
+
+ if (stat (device_file, &stat_buf) != 0)
+ goto out;
+
+ if (stat_buf.st_rdev == 0)
+ goto out;
+
+ if (S_ISBLK (stat_buf.st_mode))
+ device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
+ else if (S_ISCHR (stat_buf.st_mode))
+ device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);
+
+ out:
+ return device;
+}
+
+/**
+ * g_udev_client_query_by_sysfs_path:
+ * @client: A #GUdevClient.
+ * @sysfs_path: A sysfs path.
+ *
+ * Looks up a device for a sysfs path.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_sysfs_path (GUdevClient *client,
+ const gchar *sysfs_path)
+{
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (sysfs_path != NULL, NULL);
+
+ device = NULL;
+ udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+
+ out:
+ return device;
+}
+
+/**
+ * g_udev_client_query_by_subsystem_and_name:
+ * @client: A #GUdevClient.
+ * @subsystem: A subsystem name.
+ * @name: The name of the device.
+ *
+ * Looks up a device for a subsystem and name.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
+ const gchar *subsystem,
+ const gchar *name)
+{
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ device = NULL;
+ udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+
+ out:
+ return device;
+}
+
+struct udev *
+_g_udev_client_get_udev (GUdevClient *client)
+{
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ return client->priv->udev;
+}
diff --git a/src/extras/gudev/gudevclient.h b/src/extras/gudev/gudevclient.h
new file mode 100644
index 0000000000..b425d03d48
--- /dev/null
+++ b/src/extras/gudev/gudevclient.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_CLIENT_H__
+#define __G_UDEV_CLIENT_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_CLIENT (g_udev_client_get_type ())
+#define G_UDEV_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_CLIENT, GUdevClient))
+#define G_UDEV_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+#define G_UDEV_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+
+typedef struct _GUdevClientClass GUdevClientClass;
+typedef struct _GUdevClientPrivate GUdevClientPrivate;
+
+/**
+ * GUdevClient:
+ *
+ * The #GUdevClient struct is opaque and should not be accessed directly.
+ */
+struct _GUdevClient
+{
+ GObject parent;
+
+ /*< private >*/
+ GUdevClientPrivate *priv;
+};
+
+/**
+ * GUdevClientClass:
+ * @parent_class: Parent class.
+ * @uevent: Signal class handler for the #GUdevClient::uevent signal.
+ *
+ * Class structure for #GUdevClient.
+ */
+struct _GUdevClientClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*uevent) (GUdevClient *client,
+ const gchar *action,
+ GUdevDevice *device);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*reserved1) (void);
+ void (*reserved2) (void);
+ void (*reserved3) (void);
+ void (*reserved4) (void);
+ void (*reserved5) (void);
+ void (*reserved6) (void);
+ void (*reserved7) (void);
+ void (*reserved8) (void);
+};
+
+GType g_udev_client_get_type (void) G_GNUC_CONST;
+GUdevClient *g_udev_client_new (const gchar* const *subsystems);
+GList *g_udev_client_query_by_subsystem (GUdevClient *client,
+ const gchar *subsystem);
+GUdevDevice *g_udev_client_query_by_device_number (GUdevClient *client,
+ GUdevDeviceType type,
+ GUdevDeviceNumber number);
+GUdevDevice *g_udev_client_query_by_device_file (GUdevClient *client,
+ const gchar *device_file);
+GUdevDevice *g_udev_client_query_by_sysfs_path (GUdevClient *client,
+ const gchar *sysfs_path);
+GUdevDevice *g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
+ const gchar *subsystem,
+ const gchar *name);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_CLIENT_H__ */
diff --git a/src/extras/gudev/gudevdevice.c b/src/extras/gudev/gudevdevice.c
new file mode 100644
index 0000000000..0c3340ffeb
--- /dev/null
+++ b/src/extras/gudev/gudevdevice.c
@@ -0,0 +1,963 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevdevice.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevdevice
+ * @short_description: Get information about a device
+ *
+ * The #GUdevDevice class is used to get information about a specific
+ * device. Note that you cannot instantiate a #GUdevDevice object
+ * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
+ * objects.
+ *
+ * To get basic information about a device, use
+ * g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
+ * g_udev_device_get_name(), g_udev_device_get_number(),
+ * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
+ * g_udev_device_get_action(), g_udev_device_get_seqnum(),
+ * g_udev_device_get_device_type(), g_udev_device_get_device_number(),
+ * g_udev_device_get_device_file(),
+ * g_udev_device_get_device_file_symlinks().
+ *
+ * To navigate the device tree, use g_udev_device_get_parent() and
+ * g_udev_device_get_parent_with_subsystem().
+ *
+ * To access udev properties for the device, use
+ * g_udev_device_get_property_keys(),
+ * g_udev_device_has_property(),
+ * g_udev_device_get_property(),
+ * g_udev_device_get_property_as_int(),
+ * g_udev_device_get_property_as_uint64(),
+ * g_udev_device_get_property_as_double(),
+ * g_udev_device_get_property_as_boolean() and
+ * g_udev_device_get_property_as_strv().
+ *
+ * To access sysfs attributes for the device, use
+ * g_udev_device_get_sysfs_attr(),
+ * g_udev_device_get_sysfs_attr_as_int(),
+ * g_udev_device_get_sysfs_attr_as_uint64(),
+ * g_udev_device_get_sysfs_attr_as_double(),
+ * g_udev_device_get_sysfs_attr_as_boolean() and
+ * g_udev_device_get_sysfs_attr_as_strv().
+ *
+ * Note that all getters on #GUdevDevice are non-reffing – returned
+ * values are owned by the object, should not be freed and are only
+ * valid as long as the object is alive.
+ *
+ * By design, #GUdevDevice will not react to changes for a device – it
+ * only contains a snapshot of information when the #GUdevDevice
+ * object was created. To work with changes, you typically connect to
+ * the #GUdevClient::uevent signal on a #GUdevClient and get a new
+ * #GUdevDevice whenever an event happens.
+ */
+
+struct _GUdevDevicePrivate
+{
+ struct udev_device *udevice;
+
+ /* computed ondemand and cached */
+ gchar **device_file_symlinks;
+ gchar **property_keys;
+ gchar **tags;
+ GHashTable *prop_strvs;
+ GHashTable *sysfs_attr_strvs;
+};
+
+G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)
+
+static void
+g_udev_device_finalize (GObject *object)
+{
+ GUdevDevice *device = G_UDEV_DEVICE (object);
+
+ g_strfreev (device->priv->device_file_symlinks);
+ g_strfreev (device->priv->property_keys);
+ g_strfreev (device->priv->tags);
+
+ if (device->priv->udevice != NULL)
+ udev_device_unref (device->priv->udevice);
+
+ if (device->priv->prop_strvs != NULL)
+ g_hash_table_unref (device->priv->prop_strvs);
+
+ if (device->priv->sysfs_attr_strvs != NULL)
+ g_hash_table_unref (device->priv->sysfs_attr_strvs);
+
+ if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
+ (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
+}
+
+static void
+g_udev_device_class_init (GUdevDeviceClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = g_udev_device_finalize;
+
+ g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
+}
+
+static void
+g_udev_device_init (GUdevDevice *device)
+{
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
+ G_UDEV_TYPE_DEVICE,
+ GUdevDevicePrivate);
+}
+
+
+GUdevDevice *
+_g_udev_device_new (struct udev_device *udevice)
+{
+ GUdevDevice *device;
+
+ device = G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
+ device->priv->udevice = udev_device_ref (udevice);
+
+ return device;
+}
+
+/**
+ * g_udev_device_get_subsystem:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the subsystem for @device.
+ *
+ * Returns: The subsystem for @device.
+ */
+const gchar *
+g_udev_device_get_subsystem (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_subsystem (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_devtype:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device type for @device.
+ *
+ * Returns: The devtype for @device.
+ */
+const gchar *
+g_udev_device_get_devtype (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_devtype (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_name:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the name of @device, e.g. "sda3".
+ *
+ * Returns: The name of @device.
+ */
+const gchar *
+g_udev_device_get_name (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_sysname (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_number:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
+ *
+ * Returns: The number of @device.
+ */
+const gchar *
+g_udev_device_get_number (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_sysnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_sysfs_path:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the sysfs path for @device.
+ *
+ * Returns: The sysfs path for @device.
+ */
+const gchar *
+g_udev_device_get_sysfs_path (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_syspath (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_driver:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the name of the driver used for @device.
+ *
+ * Returns: The name of the driver for @device or %NULL if unknown.
+ */
+const gchar *
+g_udev_device_get_driver (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_driver (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_action:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
+ *
+ * Returns: An action string.
+ */
+const gchar *
+g_udev_device_get_action (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_action (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_seqnum:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the most recent sequence number for @device.
+ *
+ * Returns: A sequence number.
+ */
+guint64
+g_udev_device_get_seqnum (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ return udev_device_get_seqnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_type:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the type of the device file, if any, for @device.
+ *
+ * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
+ */
+GUdevDeviceType
+g_udev_device_get_device_type (GUdevDevice *device)
+{
+ struct stat stat_buf;
+ const gchar *device_file;
+ GUdevDeviceType type;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);
+
+ type = G_UDEV_DEVICE_TYPE_NONE;
+
+ /* TODO: would be better to have support for this in libudev... */
+
+ device_file = g_udev_device_get_device_file (device);
+ if (device_file == NULL)
+ goto out;
+
+ if (stat (device_file, &stat_buf) != 0)
+ goto out;
+
+ if (S_ISBLK (stat_buf.st_mode))
+ type = G_UDEV_DEVICE_TYPE_BLOCK;
+ else if (S_ISCHR (stat_buf.st_mode))
+ type = G_UDEV_DEVICE_TYPE_CHAR;
+
+ out:
+ return type;
+}
+
+/**
+ * g_udev_device_get_device_number:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device number, if any, for @device.
+ *
+ * Returns: The device number for @device or 0 if unknown.
+ */
+GUdevDeviceNumber
+g_udev_device_get_device_number (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ return udev_device_get_devnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_file:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device file for @device.
+ *
+ * Returns: The device file for @device or %NULL if no device file
+ * exists.
+ */
+const gchar *
+g_udev_device_get_device_file (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_devnode (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_file_symlinks:
+ * @device: A #GUdevDevice.
+ *
+ * Gets a list of symlinks (in <literal>/dev</literal>) that points to
+ * the device file for @device.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar * const *
+g_udev_device_get_device_file_symlinks (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->device_file_symlinks != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->device_file_symlinks;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_parent:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the immediate parent of @device, if any.
+ *
+ * Returns: A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_device_get_parent (GUdevDevice *device)
+{
+ GUdevDevice *ret;
+ struct udev_device *udevice;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ ret = NULL;
+
+ udevice = udev_device_get_parent (device->priv->udevice);
+ if (udevice == NULL)
+ goto out;
+
+ ret = _g_udev_device_new (udevice);
+
+ out:
+ return ret;
+}
+
+/**
+ * g_udev_device_get_parent_with_subsystem:
+ * @device: A #GUdevDevice.
+ * @subsystem: The subsystem of the parent to get.
+ * @devtype: (allow-none): The devtype of the parent to get or %NULL.
+ *
+ * Walks up the chain of parents of @device and returns the first
+ * device encountered where @subsystem and @devtype matches, if any.
+ *
+ * Returns: A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
+ const gchar *subsystem,
+ const gchar *devtype)
+{
+ GUdevDevice *ret;
+ struct udev_device *udevice;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+
+ ret = NULL;
+
+ udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
+ subsystem,
+ devtype);
+ if (udevice == NULL)
+ goto out;
+
+ ret = _g_udev_device_new (udevice);
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_property_keys:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all keys for properties on @device.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar* const *
+g_udev_device_get_property_keys (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->property_keys != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->property_keys;
+}
+
+
+/**
+ * g_udev_device_has_property:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Check if a the property with the given key exists.
+ *
+ * Returns: %TRUE only if the value for @key exist.
+ */
+gboolean
+g_udev_device_has_property (GUdevDevice *device,
+ const gchar *key)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ return udev_device_get_property_value (device->priv->udevice, key) != NULL;
+}
+
+/**
+ * g_udev_device_get_property:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device.
+ *
+ * Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device.
+ */
+const gchar *
+g_udev_device_get_property (GUdevDevice *device,
+ const gchar *key)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ return udev_device_get_property_value (device->priv->udevice, key);
+}
+
+/**
+ * g_udev_device_get_property_as_int:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an integer
+ * using strtol().
+ *
+ * Returns: The value for @key or 0 if @key doesn't exist or
+ * isn't an integer.
+ */
+gint
+g_udev_device_get_property_as_int (GUdevDevice *device,
+ const gchar *key)
+{
+ gint result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (key != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = strtol (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_uint64:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an unsigned
+ * 64-bit integer using g_ascii_strtoull().
+ *
+ * Returns: The value for @key or 0 if @key doesn't exist or isn't a
+ * #guint64.
+ */
+guint64
+g_udev_device_get_property_as_uint64 (GUdevDevice *device,
+ const gchar *key)
+{
+ guint64 result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (key != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = g_ascii_strtoull (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_double:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to a double
+ * precision floating point number using strtod().
+ *
+ * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
+ * #gdouble.
+ */
+gdouble
+g_udev_device_get_property_as_double (GUdevDevice *device,
+ const gchar *key)
+{
+ gdouble result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
+ g_return_val_if_fail (key != NULL, 0.0);
+
+ result = 0.0;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = strtod (s, NULL);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_boolean:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an
+ * boolean. This is done by doing a case-insensitive string comparison
+ * on the string value against "1" and "true".
+ *
+ * Returns: The value for @key or %FALSE if @key doesn't exist or
+ * isn't a #gboolean.
+ */
+gboolean
+g_udev_device_get_property_as_boolean (GUdevDevice *device,
+ const gchar *key)
+{
+ gboolean result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ result = FALSE;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
+ result = TRUE;
+ out:
+ return result;
+}
+
+static gchar **
+split_at_whitespace (const gchar *s)
+{
+ gchar **result;
+ guint n;
+ guint m;
+
+ result = g_strsplit_set (s, " \v\t\r\n", 0);
+
+ /* remove empty strings, thanks GLib */
+ for (n = 0; result[n] != NULL; n++)
+ {
+ if (strlen (result[n]) == 0)
+ {
+ g_free (result[n]);
+ for (m = n; result[m] != NULL; m++)
+ result[m] = result[m + 1];
+ n--;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_strv:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and return the result of
+ * splitting it into non-empty tokens split at white space (only space
+ * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
+ * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
+ * locale is not taken into account).
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar* const *
+g_udev_device_get_property_as_strv (GUdevDevice *device,
+ const gchar *key)
+{
+ gchar **result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ if (device->priv->prop_strvs != NULL)
+ {
+ result = g_hash_table_lookup (device->priv->prop_strvs, key);
+ if (result != NULL)
+ goto out;
+ }
+
+ result = NULL;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = split_at_whitespace (s);
+ if (result == NULL)
+ goto out;
+
+ if (device->priv->prop_strvs == NULL)
+ device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+ g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);
+
+out:
+ return (const gchar* const *) result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_sysfs_attr:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device.
+ *
+ * Returns: The value of the sysfs attribute or %NULL if there is no
+ * such attribute. Do not free this string, it is owned by @device.
+ */
+const gchar *
+g_udev_device_get_sysfs_attr (GUdevDevice *device,
+ const gchar *name)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ return udev_device_get_sysattr_value (device->priv->udevice, name);
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_int:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an integer
+ * using strtol().
+ *
+ * Returns: The value of the sysfs attribute or 0 if there is no such
+ * attribute.
+ */
+gint
+g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
+ const gchar *name)
+{
+ gint result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (name != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = strtol (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_uint64:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an unsigned
+ * 64-bit integer using g_ascii_strtoull().
+ *
+ * Returns: The value of the sysfs attribute or 0 if there is no such
+ * attribute.
+ */
+guint64
+g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
+ const gchar *name)
+{
+ guint64 result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (name != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = g_ascii_strtoull (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_double:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to a double
+ * precision floating point number using strtod().
+ *
+ * Returns: The value of the sysfs attribute or 0.0 if there is no such
+ * attribute.
+ */
+gdouble
+g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
+ const gchar *name)
+{
+ gdouble result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
+ g_return_val_if_fail (name != NULL, 0.0);
+
+ result = 0.0;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = strtod (s, NULL);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_boolean:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an
+ * boolean. This is done by doing a case-insensitive string comparison
+ * on the string value against "1" and "true".
+ *
+ * Returns: The value of the sysfs attribute or %FALSE if there is no such
+ * attribute.
+ */
+gboolean
+g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
+ const gchar *name)
+{
+ gboolean result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ result = FALSE;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
+ result = TRUE;
+ out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_strv:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and return the result of
+ * splitting it into non-empty tokens split at white space (only space (' '),
+ * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
+ * tab ('\t'), and vertical tab ('\v') are considered; the locale is
+ * not taken into account).
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar * const *
+g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
+ const gchar *name)
+{
+ gchar **result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ if (device->priv->sysfs_attr_strvs != NULL)
+ {
+ result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
+ if (result != NULL)
+ goto out;
+ }
+
+ result = NULL;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = split_at_whitespace (s);
+ if (result == NULL)
+ goto out;
+
+ if (device->priv->sysfs_attr_strvs == NULL)
+ device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+ g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);
+
+out:
+ return (const gchar* const *) result;
+}
+
+/**
+ * g_udev_device_get_tags:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all tags for @device.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller.
+ *
+ * Since: 165
+ */
+const gchar* const *
+g_udev_device_get_tags (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->tags != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->tags;
+}
+
+/**
+ * g_udev_device_get_is_initialized:
+ * @device: A #GUdevDevice.
+ *
+ * Gets whether @device has been initalized.
+ *
+ * Returns: Whether @device has been initialized.
+ *
+ * Since: 165
+ */
+gboolean
+g_udev_device_get_is_initialized (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ return udev_device_get_is_initialized (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_usec_since_initialized:
+ * @device: A #GUdevDevice.
+ *
+ * Gets number of micro-seconds since @device was initialized.
+ *
+ * This only works for devices with properties in the udev
+ * database. All other devices return 0.
+ *
+ * Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
+ *
+ * Since: 165
+ */
+guint64
+g_udev_device_get_usec_since_initialized (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ return udev_device_get_usec_since_initialized (device->priv->udevice);
+}
diff --git a/src/extras/gudev/gudevdevice.h b/src/extras/gudev/gudevdevice.h
new file mode 100644
index 0000000000..d4873bad0f
--- /dev/null
+++ b/src/extras/gudev/gudevdevice.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_DEVICE_H__
+#define __G_UDEV_DEVICE_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_DEVICE (g_udev_device_get_type ())
+#define G_UDEV_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_DEVICE, GUdevDevice))
+#define G_UDEV_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+#define G_UDEV_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+
+typedef struct _GUdevDeviceClass GUdevDeviceClass;
+typedef struct _GUdevDevicePrivate GUdevDevicePrivate;
+
+/**
+ * GUdevDevice:
+ *
+ * The #GUdevDevice struct is opaque and should not be accessed directly.
+ */
+struct _GUdevDevice
+{
+ GObject parent;
+
+ /*< private >*/
+ GUdevDevicePrivate *priv;
+};
+
+/**
+ * GUdevDeviceClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #GUdevDevice.
+ */
+struct _GUdevDeviceClass
+{
+ GObjectClass parent_class;
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*reserved1) (void);
+ void (*reserved2) (void);
+ void (*reserved3) (void);
+ void (*reserved4) (void);
+ void (*reserved5) (void);
+ void (*reserved6) (void);
+ void (*reserved7) (void);
+ void (*reserved8) (void);
+};
+
+GType g_udev_device_get_type (void) G_GNUC_CONST;
+gboolean g_udev_device_get_is_initialized (GUdevDevice *device);
+guint64 g_udev_device_get_usec_since_initialized (GUdevDevice *device);
+const gchar *g_udev_device_get_subsystem (GUdevDevice *device);
+const gchar *g_udev_device_get_devtype (GUdevDevice *device);
+const gchar *g_udev_device_get_name (GUdevDevice *device);
+const gchar *g_udev_device_get_number (GUdevDevice *device);
+const gchar *g_udev_device_get_sysfs_path (GUdevDevice *device);
+const gchar *g_udev_device_get_driver (GUdevDevice *device);
+const gchar *g_udev_device_get_action (GUdevDevice *device);
+guint64 g_udev_device_get_seqnum (GUdevDevice *device);
+GUdevDeviceType g_udev_device_get_device_type (GUdevDevice *device);
+GUdevDeviceNumber g_udev_device_get_device_number (GUdevDevice *device);
+const gchar *g_udev_device_get_device_file (GUdevDevice *device);
+const gchar* const *g_udev_device_get_device_file_symlinks (GUdevDevice *device);
+GUdevDevice *g_udev_device_get_parent (GUdevDevice *device);
+GUdevDevice *g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
+ const gchar *subsystem,
+ const gchar *devtype);
+const gchar* const *g_udev_device_get_property_keys (GUdevDevice *device);
+gboolean g_udev_device_has_property (GUdevDevice *device,
+ const gchar *key);
+const gchar *g_udev_device_get_property (GUdevDevice *device,
+ const gchar *key);
+gint g_udev_device_get_property_as_int (GUdevDevice *device,
+ const gchar *key);
+guint64 g_udev_device_get_property_as_uint64 (GUdevDevice *device,
+ const gchar *key);
+gdouble g_udev_device_get_property_as_double (GUdevDevice *device,
+ const gchar *key);
+gboolean g_udev_device_get_property_as_boolean (GUdevDevice *device,
+ const gchar *key);
+const gchar* const *g_udev_device_get_property_as_strv (GUdevDevice *device,
+ const gchar *key);
+
+const gchar *g_udev_device_get_sysfs_attr (GUdevDevice *device,
+ const gchar *name);
+gint g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
+ const gchar *name);
+guint64 g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
+ const gchar *name);
+gdouble g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
+ const gchar *name);
+gboolean g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
+ const gchar *name);
+const gchar* const *g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
+ const gchar *name);
+const gchar* const *g_udev_device_get_tags (GUdevDevice *device);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_DEVICE_H__ */
diff --git a/src/extras/gudev/gudevenumerator.c b/src/extras/gudev/gudevenumerator.c
new file mode 100644
index 0000000000..db09074625
--- /dev/null
+++ b/src/extras/gudev/gudevenumerator.c
@@ -0,0 +1,431 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevclient.h"
+#include "gudevenumerator.h"
+#include "gudevdevice.h"
+#include "gudevmarshal.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevenumerator
+ * @short_description: Lookup and sort devices
+ *
+ * #GUdevEnumerator is used to lookup and sort devices.
+ *
+ * Since: 165
+ */
+
+struct _GUdevEnumeratorPrivate
+{
+ GUdevClient *client;
+ struct udev_enumerate *e;
+};
+
+enum
+{
+ PROP_0,
+ PROP_CLIENT,
+};
+
+G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+g_udev_enumerator_finalize (GObject *object)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ if (enumerator->priv->client != NULL)
+ {
+ g_object_unref (enumerator->priv->client);
+ enumerator->priv->client = NULL;
+ }
+
+ if (enumerator->priv->e != NULL)
+ {
+ udev_enumerate_unref (enumerator->priv->e);
+ enumerator->priv->e = NULL;
+ }
+
+ if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
+}
+
+static void
+g_udev_enumerator_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_CLIENT:
+ if (enumerator->priv->client != NULL)
+ g_object_unref (enumerator->priv->client);
+ enumerator->priv->client = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_enumerator_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_CLIENT:
+ g_value_set_object (value, enumerator->priv->client);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_enumerator_constructed (GObject *object)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
+
+ enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
+
+ if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
+}
+
+static void
+g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = g_udev_enumerator_finalize;
+ gobject_class->set_property = g_udev_enumerator_set_property;
+ gobject_class->get_property = g_udev_enumerator_get_property;
+ gobject_class->constructed = g_udev_enumerator_constructed;
+
+ /**
+ * GUdevEnumerator:client:
+ *
+ * The #GUdevClient to enumerate devices from.
+ *
+ * Since: 165
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CLIENT,
+ g_param_spec_object ("client",
+ "The client to enumerate devices from",
+ "The client to enumerate devices from",
+ G_UDEV_TYPE_CLIENT,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
+}
+
+static void
+g_udev_enumerator_init (GUdevEnumerator *enumerator)
+{
+ enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
+ G_UDEV_TYPE_ENUMERATOR,
+ GUdevEnumeratorPrivate);
+}
+
+/**
+ * g_udev_enumerator_new:
+ * @client: A #GUdevClient to enumerate devices from.
+ *
+ * Constructs a #GUdevEnumerator object that can be used to enumerate
+ * and sort devices. Use the add_match_*() and add_nomatch_*() methods
+ * and execute the query to get a list of devices with
+ * g_udev_enumerator_execute().
+ *
+ * Returns: A new #GUdevEnumerator object. Free with g_object_unref().
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_new (GUdevClient *client)
+{
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
+}
+
+
+/**
+ * g_udev_enumerator_add_match_subsystem:
+ * @enumerator: A #GUdevEnumerator.
+ * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
+ *
+ * All returned devices will match the given @subsystem.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+ udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_nomatch_subsystem:
+ * @enumerator: A #GUdevEnumerator.
+ * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
+ *
+ * All returned devices will not match the given @subsystem.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+ udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_sysfs_attr:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for sysfs attribute key.
+ * @value: Wildcard filter for sysfs attribute value.
+ *
+ * All returned devices will have a sysfs attribute matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_nomatch_sysfs_attr:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for sysfs attribute key.
+ * @value: Wildcard filter for sysfs attribute value.
+ *
+ * All returned devices will not have a sysfs attribute matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_property:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for property name.
+ * @value: Wildcard filter for property value.
+ *
+ * All returned devices will have a property matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ udev_enumerate_add_match_property (enumerator->priv->e, name, value);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_name:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for kernel name e.g. "sda*".
+ *
+ * All returned devices will match the given @name.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
+ const gchar *name)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ udev_enumerate_add_match_sysname (enumerator->priv->e, name);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_sysfs_path:
+ * @enumerator: A #GUdevEnumerator.
+ * @sysfs_path: A sysfs path, e.g. "/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda"
+ *
+ * Add a device to the list of devices, to retrieve it back sorted in dependency order.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
+ const gchar *sysfs_path)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (sysfs_path != NULL, NULL);
+ udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_tag:
+ * @enumerator: A #GUdevEnumerator.
+ * @tag: A udev tag e.g. "udev-acl".
+ *
+ * All returned devices will match the given @tag.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
+ const gchar *tag)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (tag != NULL, NULL);
+ udev_enumerate_add_match_tag (enumerator->priv->e, tag);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_is_initialized:
+ * @enumerator: A #GUdevEnumerator.
+ *
+ * All returned devices will be initialized.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ udev_enumerate_add_match_is_initialized (enumerator->priv->e);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_execute:
+ * @enumerator: A #GUdevEnumerator.
+ *
+ * Executes the query in @enumerator.
+ *
+ * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
+ *
+ * Since: 165
+ */
+GList *
+g_udev_enumerator_execute (GUdevEnumerator *enumerator)
+{
+ GList *ret;
+ struct udev_list_entry *l, *devices;
+
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+
+ ret = NULL;
+
+ /* retrieve the list */
+ udev_enumerate_scan_devices (enumerator->priv->e);
+
+ devices = udev_enumerate_get_list_entry (enumerator->priv->e);
+ for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
+ {
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
+ udev_list_entry_get_name (l));
+ if (udevice == NULL)
+ continue;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+ ret = g_list_prepend (ret, device);
+ }
+
+ ret = g_list_reverse (ret);
+
+ return ret;
+}
diff --git a/src/extras/gudev/gudevenumerator.h b/src/extras/gudev/gudevenumerator.h
new file mode 100644
index 0000000000..3fddccf573
--- /dev/null
+++ b/src/extras/gudev/gudevenumerator.h
@@ -0,0 +1,107 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_ENUMERATOR_H__
+#define __G_UDEV_ENUMERATOR_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_ENUMERATOR (g_udev_enumerator_get_type ())
+#define G_UDEV_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumerator))
+#define G_UDEV_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
+#define G_UDEV_IS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_ENUMERATOR))
+#define G_UDEV_IS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_ENUMERATOR))
+#define G_UDEV_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
+
+typedef struct _GUdevEnumeratorClass GUdevEnumeratorClass;
+typedef struct _GUdevEnumeratorPrivate GUdevEnumeratorPrivate;
+
+/**
+ * GUdevEnumerator:
+ *
+ * The #GUdevEnumerator struct is opaque and should not be accessed directly.
+ *
+ * Since: 165
+ */
+struct _GUdevEnumerator
+{
+ GObject parent;
+
+ /*< private >*/
+ GUdevEnumeratorPrivate *priv;
+};
+
+/**
+ * GUdevEnumeratorClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #GUdevEnumerator.
+ *
+ * Since: 165
+ */
+struct _GUdevEnumeratorClass
+{
+ GObjectClass parent_class;
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*reserved1) (void);
+ void (*reserved2) (void);
+ void (*reserved3) (void);
+ void (*reserved4) (void);
+ void (*reserved5) (void);
+ void (*reserved6) (void);
+ void (*reserved7) (void);
+ void (*reserved8) (void);
+};
+
+GType g_udev_enumerator_get_type (void) G_GNUC_CONST;
+GUdevEnumerator *g_udev_enumerator_new (GUdevClient *client);
+GUdevEnumerator *g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem);
+GUdevEnumerator *g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem);
+GUdevEnumerator *g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value);
+GUdevEnumerator *g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value);
+GUdevEnumerator *g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value);
+GUdevEnumerator *g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
+ const gchar *name);
+GUdevEnumerator *g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
+ const gchar *tag);
+GUdevEnumerator *g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator);
+GUdevEnumerator *g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
+ const gchar *sysfs_path);
+GList *g_udev_enumerator_execute (GUdevEnumerator *enumerator);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_ENUMERATOR_H__ */
diff --git a/src/extras/gudev/gudevenums.h b/src/extras/gudev/gudevenums.h
new file mode 100644
index 0000000000..c3a0aa8747
--- /dev/null
+++ b/src/extras/gudev/gudevenums.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_ENUMS_H__
+#define __G_UDEV_ENUMS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GUdevDeviceType:
+ * @G_UDEV_DEVICE_TYPE_NONE: Device does not have a device file.
+ * @G_UDEV_DEVICE_TYPE_BLOCK: Device is a block device.
+ * @G_UDEV_DEVICE_TYPE_CHAR: Device is a character device.
+ *
+ * Enumeration used to specify a the type of a device.
+ */
+typedef enum
+{
+ G_UDEV_DEVICE_TYPE_NONE = 0,
+ G_UDEV_DEVICE_TYPE_BLOCK = 'b',
+ G_UDEV_DEVICE_TYPE_CHAR = 'c',
+} GUdevDeviceType;
+
+G_END_DECLS
+
+#endif /* __G_UDEV_ENUMS_H__ */
diff --git a/src/extras/gudev/gudevenumtypes.c.template b/src/extras/gudev/gudevenumtypes.c.template
new file mode 100644
index 0000000000..fc30b39e2e
--- /dev/null
+++ b/src/extras/gudev/gudevenumtypes.c.template
@@ -0,0 +1,39 @@
+/*** BEGIN file-header ***/
+#include <gudev.h>
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_define_type_id__volatile))
+ {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType g_define_type_id =
+ g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/src/extras/gudev/gudevenumtypes.h.template b/src/extras/gudev/gudevenumtypes.h.template
new file mode 100644
index 0000000000..d0ab3393e6
--- /dev/null
+++ b/src/extras/gudev/gudevenumtypes.h.template
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef __GUDEV_ENUM_TYPES_H__
+#define __GUDEV_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __GUDEV_ENUM_TYPES_H__ */
+/*** END file-tail ***/
diff --git a/src/extras/gudev/gudevmarshal.list b/src/extras/gudev/gudevmarshal.list
new file mode 100644
index 0000000000..7e665999e8
--- /dev/null
+++ b/src/extras/gudev/gudevmarshal.list
@@ -0,0 +1 @@
+VOID:STRING,OBJECT
diff --git a/src/extras/gudev/gudevprivate.h b/src/extras/gudev/gudevprivate.h
new file mode 100644
index 0000000000..8866f52b88
--- /dev/null
+++ b/src/extras/gudev/gudevprivate.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_PRIVATE_H__
+#define __G_UDEV_PRIVATE_H__
+
+#include <gudev/gudevtypes.h>
+
+#include <libudev.h>
+
+G_BEGIN_DECLS
+
+GUdevDevice *
+_g_udev_device_new (struct udev_device *udevice);
+
+struct udev *_g_udev_client_get_udev (GUdevClient *client);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_PRIVATE_H__ */
diff --git a/src/extras/gudev/gudevtypes.h b/src/extras/gudev/gudevtypes.h
new file mode 100644
index 0000000000..888482783d
--- /dev/null
+++ b/src/extras/gudev/gudevtypes.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_TYPES_H__
+#define __G_UDEV_TYPES_H__
+
+#include <gudev/gudevenums.h>
+#include <sys/types.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GUdevClient GUdevClient;
+typedef struct _GUdevDevice GUdevDevice;
+typedef struct _GUdevEnumerator GUdevEnumerator;
+
+/**
+ * GUdevDeviceNumber:
+ *
+ * Corresponds to the standard #dev_t type as defined by POSIX (Until
+ * bug 584517 is resolved this work-around is needed).
+ */
+#ifdef _GUDEV_WORK_AROUND_DEV_T_BUG
+typedef guint64 GUdevDeviceNumber; /* __UQUAD_TYPE */
+#else
+typedef dev_t GUdevDeviceNumber;
+#endif
+
+G_END_DECLS
+
+#endif /* __G_UDEV_TYPES_H__ */
diff --git a/src/extras/gudev/seed-example-enum.js b/src/extras/gudev/seed-example-enum.js
new file mode 100755
index 0000000000..66206ad806
--- /dev/null
+++ b/src/extras/gudev/seed-example-enum.js
@@ -0,0 +1,38 @@
+#!/usr/bin/env seed
+
+const GLib = imports.gi.GLib;
+const GUdev = imports.gi.GUdev;
+
+function print_device(device) {
+ print(" initialized: " + device.get_is_initialized());
+ print(" usec since initialized: " + device.get_usec_since_initialized());
+ print(" subsystem: " + device.get_subsystem());
+ print(" devtype: " + device.get_devtype());
+ print(" name: " + device.get_name());
+ print(" number: " + device.get_number());
+ print(" sysfs_path: " + device.get_sysfs_path());
+ print(" driver: " + device.get_driver());
+ print(" action: " + device.get_action());
+ print(" seqnum: " + device.get_seqnum());
+ print(" device type: " + device.get_device_type());
+ print(" device number: " + device.get_device_number());
+ print(" device file: " + device.get_device_file());
+ print(" device file symlinks: " + device.get_device_file_symlinks());
+ print(" tags: " + device.get_tags());
+ var keys = device.get_property_keys();
+ for (var n = 0; n < keys.length; n++) {
+ print(" " + keys[n] + "=" + device.get_property(keys[n]));
+ }
+}
+
+var client = new GUdev.Client({subsystems: []});
+var enumerator = new GUdev.Enumerator({client: client});
+enumerator.add_match_subsystem('b*')
+
+var devices = enumerator.execute();
+
+for (var n=0; n < devices.length; n++) {
+ var device = devices[n];
+ print_device(device);
+ print("");
+}
diff --git a/src/extras/gudev/seed-example.js b/src/extras/gudev/seed-example.js
new file mode 100755
index 0000000000..e2ac324d23
--- /dev/null
+++ b/src/extras/gudev/seed-example.js
@@ -0,0 +1,72 @@
+#!/usr/bin/env seed
+
+// seed example
+
+const GLib = imports.gi.GLib;
+const GUdev = imports.gi.GUdev;
+
+function print_device (device) {
+ print (" subsystem: " + device.get_subsystem ());
+ print (" devtype: " + device.get_devtype ());
+ print (" name: " + device.get_name ());
+ print (" number: " + device.get_number ());
+ print (" sysfs_path: " + device.get_sysfs_path ());
+ print (" driver: " + device.get_driver ());
+ print (" action: " + device.get_action ());
+ print (" seqnum: " + device.get_seqnum ());
+ print (" device type: " + device.get_device_type ());
+ print (" device number: " + device.get_device_number ());
+ print (" device file: " + device.get_device_file ());
+ print (" device file symlinks: " + device.get_device_file_symlinks ());
+ print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
+ var keys = device.get_property_keys ();
+ for (var n = 0; n < keys.length; n++) {
+ print (" " + keys[n] + "=" + device.get_property (keys[n]));
+ }
+}
+
+function on_uevent (client, action, device) {
+ print ("action " + action + " on device " + device.get_sysfs_path());
+ print_device (device);
+ print ("");
+}
+
+var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
+client.signal.connect ("uevent", on_uevent);
+
+var block_devices = client.query_by_subsystem ("block");
+for (var n = 0; n < block_devices.length; n++) {
+ print ("block device: " + block_devices[n].get_device_file ());
+}
+
+var d;
+
+d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
+if (d == null) {
+ print ("query_by_device_number 0x810 -> null");
+} else {
+ print ("query_by_device_number 0x810 -> " + d.get_device_file ());
+ dd = d.get_parent_with_subsystem ("usb", null);
+ print_device (dd);
+ print ("--------------------------------------------------------------------------");
+ while (d != null) {
+ print_device (d);
+ print ("");
+ d = d.get_parent ();
+ }
+}
+
+d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
+print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
+
+d = client.query_by_subsystem_and_name ("block", "sda2");
+print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/sda");
+print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/block/8:0");
+print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
+
+var mainloop = GLib.main_loop_new ();
+GLib.main_loop_run (mainloop);