diff options
85 files changed, 8733 insertions, 0 deletions
@@ -0,0 +1,2 @@ | |||
1 | Andrew Cann <shum@canndrew.org> | ||
2 | |||
@@ -0,0 +1,674 @@ | |||
1 | GNU GENERAL PUBLIC LICENSE | ||
2 | Version 3, 29 June 2007 | ||
3 | |||
4 | Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | ||
5 | Everyone is permitted to copy and distribute verbatim copies | ||
6 | of this license document, but changing it is not allowed. | ||
7 | |||
8 | Preamble | ||
9 | |||
10 | The GNU General Public License is a free, copyleft license for | ||
11 | software and other kinds of works. | ||
12 | |||
13 | The licenses for most software and other practical works are designed | ||
14 | to take away your freedom to share and change the works. By contrast, | ||
15 | the GNU General Public License is intended to guarantee your freedom to | ||
16 | share and change all versions of a program--to make sure it remains free | ||
17 | software for all its users. We, the Free Software Foundation, use the | ||
18 | GNU General Public License for most of our software; it applies also to | ||
19 | any other work released this way by its authors. You can apply it to | ||
20 | your programs, too. | ||
21 | |||
22 | When we speak of free software, we are referring to freedom, not | ||
23 | price. Our General Public Licenses are designed to make sure that you | ||
24 | have the freedom to distribute copies of free software (and charge for | ||
25 | them if you wish), that you receive source code or can get it if you | ||
26 | want it, that you can change the software or use pieces of it in new | ||
27 | free programs, and that you know you can do these things. | ||
28 | |||
29 | To protect your rights, we need to prevent others from denying you | ||
30 | these rights or asking you to surrender the rights. Therefore, you have | ||
31 | certain responsibilities if you distribute copies of the software, or if | ||
32 | you modify it: responsibilities to respect the freedom of others. | ||
33 | |||
34 | For example, if you distribute copies of such a program, whether | ||
35 | gratis or for a fee, you must pass on to the recipients the same | ||
36 | freedoms that you received. You must make sure that they, too, receive | ||
37 | or can get the source code. And you must show them these terms so they | ||
38 | know their rights. | ||
39 | |||
40 | Developers that use the GNU GPL protect your rights with two steps: | ||
41 | (1) assert copyright on the software, and (2) offer you this License | ||
42 | giving you legal permission to copy, distribute and/or modify it. | ||
43 | |||
44 | For the developers' and authors' protection, the GPL clearly explains | ||
45 | that there is no warranty for this free software. For both users' and | ||
46 | authors' sake, the GPL requires that modified versions be marked as | ||
47 | changed, so that their problems will not be attributed erroneously to | ||
48 | authors of previous versions. | ||
49 | |||
50 | Some devices are designed to deny users access to install or run | ||
51 | modified versions of the software inside them, although the manufacturer | ||
52 | can do so. This is fundamentally incompatible with the aim of | ||
53 | protecting users' freedom to change the software. The systematic | ||
54 | pattern of such abuse occurs in the area of products for individuals to | ||
55 | use, which is precisely where it is most unacceptable. Therefore, we | ||
56 | have designed this version of the GPL to prohibit the practice for those | ||
57 | products. If such problems arise substantially in other domains, we | ||
58 | stand ready to extend this provision to those domains in future versions | ||
59 | of the GPL, as needed to protect the freedom of users. | ||
60 | |||
61 | Finally, every program is threatened constantly by software patents. | ||
62 | States should not allow patents to restrict development and use of | ||
63 | software on general-purpose computers, but in those that do, we wish to | ||
64 | avoid the special danger that patents applied to a free program could | ||
65 | make it effectively proprietary. To prevent this, the GPL assures that | ||
66 | patents cannot be used to render the program non-free. | ||
67 | |||
68 | The precise terms and conditions for copying, distribution and | ||
69 | modification follow. | ||
70 | |||
71 | TERMS AND CONDITIONS | ||
72 | |||
73 | 0. Definitions. | ||
74 | |||
75 | "This License" refers to version 3 of the GNU General Public License. | ||
76 | |||
77 | "Copyright" also means copyright-like laws that apply to other kinds of | ||
78 | works, such as semiconductor masks. | ||
79 | |||
80 | "The Program" refers to any copyrightable work licensed under this | ||
81 | License. Each licensee is addressed as "you". "Licensees" and | ||
82 | "recipients" may be individuals or organizations. | ||
83 | |||
84 | To "modify" a work means to copy from or adapt all or part of the work | ||
85 | in a fashion requiring copyright permission, other than the making of an | ||
86 | exact copy. The resulting work is called a "modified version" of the | ||
87 | earlier work or a work "based on" the earlier work. | ||
88 | |||
89 | A "covered work" means either the unmodified Program or a work based | ||
90 | on the Program. | ||
91 | |||
92 | To "propagate" a work means to do anything with it that, without | ||
93 | permission, would make you directly or secondarily liable for | ||
94 | infringement under applicable copyright law, except executing it on a | ||
95 | computer or modifying a private copy. Propagation includes copying, | ||
96 | distribution (with or without modification), making available to the | ||
97 | public, and in some countries other activities as well. | ||
98 | |||
99 | To "convey" a work means any kind of propagation that enables other | ||
100 | parties to make or receive copies. Mere interaction with a user through | ||
101 | a computer network, with no transfer of a copy, is not conveying. | ||
102 | |||
103 | An interactive user interface displays "Appropriate Legal Notices" | ||
104 | to the extent that it includes a convenient and prominently visible | ||
105 | feature that (1) displays an appropriate copyright notice, and (2) | ||
106 | tells the user that there is no warranty for the work (except to the | ||
107 | extent that warranties are provided), that licensees may convey the | ||
108 | work under this License, and how to view a copy of this License. If | ||
109 | the interface presents a list of user commands or options, such as a | ||
110 | menu, a prominent item in the list meets this criterion. | ||
111 | |||
112 | 1. Source Code. | ||
113 | |||
114 | The "source code" for a work means the preferred form of the work | ||
115 | for making modifications to it. "Object code" means any non-source | ||
116 | form of a work. | ||
117 | |||
118 | A "Standard Interface" means an interface that either is an official | ||
119 | standard defined by a recognized standards body, or, in the case of | ||
120 | interfaces specified for a particular programming language, one that | ||
121 | is widely used among developers working in that language. | ||
122 | |||
123 | The "System Libraries" of an executable work include anything, other | ||
124 | than the work as a whole, that (a) is included in the normal form of | ||
125 | packaging a Major Component, but which is not part of that Major | ||
126 | Component, and (b) serves only to enable use of the work with that | ||
127 | Major Component, or to implement a Standard Interface for which an | ||
128 | implementation is available to the public in source code form. A | ||
129 | "Major Component", in this context, means a major essential component | ||
130 | (kernel, window system, and so on) of the specific operating system | ||
131 | (if any) on which the executable work runs, or a compiler used to | ||
132 | produce the work, or an object code interpreter used to run it. | ||
133 | |||
134 | The "Corresponding Source" for a work in object code form means all | ||
135 | the source code needed to generate, install, and (for an executable | ||
136 | work) run the object code and to modify the work, including scripts to | ||
137 | control those activities. However, it does not include the work's | ||
138 | System Libraries, or general-purpose tools or generally available free | ||
139 | programs which are used unmodified in performing those activities but | ||
140 | which are not part of the work. For example, Corresponding Source | ||
141 | includes interface definition files associated with source files for | ||
142 | the work, and the source code for shared libraries and dynamically | ||
143 | linked subprograms that the work is specifically designed to require, | ||
144 | such as by intimate data communication or control flow between those | ||
145 | subprograms and other parts of the work. | ||
146 | |||
147 | The Corresponding Source need not include anything that users | ||
148 | can regenerate automatically from other parts of the Corresponding | ||
149 | Source. | ||
150 | |||
151 | The Corresponding Source for a work in source code form is that | ||
152 | same work. | ||
153 | |||
154 | 2. Basic Permissions. | ||
155 | |||
156 | All rights granted under this License are granted for the term of | ||
157 | copyright on the Program, and are irrevocable provided the stated | ||
158 | conditions are met. This License explicitly affirms your unlimited | ||
159 | permission to run the unmodified Program. The output from running a | ||
160 | covered work is covered by this License only if the output, given its | ||
161 | content, constitutes a covered work. This License acknowledges your | ||
162 | rights of fair use or other equivalent, as provided by copyright law. | ||
163 | |||
164 | You may make, run and propagate covered works that you do not | ||
165 | convey, without conditions so long as your license otherwise remains | ||
166 | in force. You may convey covered works to others for the sole purpose | ||
167 | of having them make modifications exclusively for you, or provide you | ||
168 | with facilities for running those works, provided that you comply with | ||
169 | the terms of this License in conveying all material for which you do | ||
170 | not control copyright. Those thus making or running the covered works | ||
171 | for you must do so exclusively on your behalf, under your direction | ||
172 | and control, on terms that prohibit them from making any copies of | ||
173 | your copyrighted material outside their relationship with you. | ||
174 | |||
175 | Conveying under any other circumstances is permitted solely under | ||
176 | the conditions stated below. Sublicensing is not allowed; section 10 | ||
177 | makes it unnecessary. | ||
178 | |||
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. | ||
180 | |||
181 | No covered work shall be deemed part of an effective technological | ||
182 | measure under any applicable law fulfilling obligations under article | ||
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or | ||
184 | similar laws prohibiting or restricting circumvention of such | ||
185 | measures. | ||
186 | |||
187 | When you convey a covered work, you waive any legal power to forbid | ||
188 | circumvention of technological measures to the extent such circumvention | ||
189 | is effected by exercising rights under this License with respect to | ||
190 | the covered work, and you disclaim any intention to limit operation or | ||
191 | modification of the work as a means of enforcing, against the work's | ||
192 | users, your or third parties' legal rights to forbid circumvention of | ||
193 | technological measures. | ||
194 | |||
195 | 4. Conveying Verbatim Copies. | ||
196 | |||
197 | You may convey verbatim copies of the Program's source code as you | ||
198 | receive it, in any medium, provided that you conspicuously and | ||
199 | appropriately publish on each copy an appropriate copyright notice; | ||
200 | keep intact all notices stating that this License and any | ||
201 | non-permissive terms added in accord with section 7 apply to the code; | ||
202 | keep intact all notices of the absence of any warranty; and give all | ||
203 | recipients a copy of this License along with the Program. | ||
204 | |||
205 | You may charge any price or no price for each copy that you convey, | ||
206 | and you may offer support or warranty protection for a fee. | ||
207 | |||
208 | 5. Conveying Modified Source Versions. | ||
209 | |||
210 | You may convey a work based on the Program, or the modifications to | ||
211 | produce it from the Program, in the form of source code under the | ||
212 | terms of section 4, provided that you also meet all of these conditions: | ||
213 | |||
214 | a) The work must carry prominent notices stating that you modified | ||
215 | it, and giving a relevant date. | ||
216 | |||
217 | b) The work must carry prominent notices stating that it is | ||
218 | released under this License and any conditions added under section | ||
219 | 7. This requirement modifies the requirement in section 4 to | ||
220 | "keep intact all notices". | ||
221 | |||
222 | c) You must license the entire work, as a whole, under this | ||
223 | License to anyone who comes into possession of a copy. This | ||
224 | License will therefore apply, along with any applicable section 7 | ||
225 | additional terms, to the whole of the work, and all its parts, | ||
226 | regardless of how they are packaged. This License gives no | ||
227 | permission to license the work in any other way, but it does not | ||
228 | invalidate such permission if you have separately received it. | ||
229 | |||
230 | d) If the work has interactive user interfaces, each must display | ||
231 | Appropriate Legal Notices; however, if the Program has interactive | ||
232 | interfaces that do not display Appropriate Legal Notices, your | ||
233 | work need not make them do so. | ||
234 | |||
235 | A compilation of a covered work with other separate and independent | ||
236 | works, which are not by their nature extensions of the covered work, | ||
237 | and which are not combined with it such as to form a larger program, | ||
238 | in or on a volume of a storage or distribution medium, is called an | ||
239 | "aggregate" if the compilation and its resulting copyright are not | ||
240 | used to limit the access or legal rights of the compilation's users | ||
241 | beyond what the individual works permit. Inclusion of a covered work | ||
242 | in an aggregate does not cause this License to apply to the other | ||
243 | parts of the aggregate. | ||
244 | |||
245 | 6. Conveying Non-Source Forms. | ||
246 | |||
247 | You may convey a covered work in object code form under the terms | ||
248 | of sections 4 and 5, provided that you also convey the | ||
249 | machine-readable Corresponding Source under the terms of this License, | ||
250 | in one of these ways: | ||
251 | |||
252 | a) Convey the object code in, or embodied in, a physical product | ||
253 | (including a physical distribution medium), accompanied by the | ||
254 | Corresponding Source fixed on a durable physical medium | ||
255 | customarily used for software interchange. | ||
256 | |||
257 | b) Convey the object code in, or embodied in, a physical product | ||
258 | (including a physical distribution medium), accompanied by a | ||
259 | written offer, valid for at least three years and valid for as | ||
260 | long as you offer spare parts or customer support for that product | ||
261 | model, to give anyone who possesses the object code either (1) a | ||
262 | copy of the Corresponding Source for all the software in the | ||
263 | product that is covered by this License, on a durable physical | ||
264 | medium customarily used for software interchange, for a price no | ||
265 | more than your reasonable cost of physically performing this | ||
266 | conveying of source, or (2) access to copy the | ||
267 | Corresponding Source from a network server at no charge. | ||
268 | |||
269 | c) Convey individual copies of the object code with a copy of the | ||
270 | written offer to provide the Corresponding Source. This | ||
271 | alternative is allowed only occasionally and noncommercially, and | ||
272 | only if you received the object code with such an offer, in accord | ||
273 | with subsection 6b. | ||
274 | |||
275 | d) Convey the object code by offering access from a designated | ||
276 | place (gratis or for a charge), and offer equivalent access to the | ||
277 | Corresponding Source in the same way through the same place at no | ||
278 | further charge. You need not require recipients to copy the | ||
279 | Corresponding Source along with the object code. If the place to | ||
280 | copy the object code is a network server, the Corresponding Source | ||
281 | may be on a different server (operated by you or a third party) | ||
282 | that supports equivalent copying facilities, provided you maintain | ||
283 | clear directions next to the object code saying where to find the | ||
284 | Corresponding Source. Regardless of what server hosts the | ||
285 | Corresponding Source, you remain obligated to ensure that it is | ||
286 | available for as long as needed to satisfy these requirements. | ||
287 | |||
288 | e) Convey the object code using peer-to-peer transmission, provided | ||
289 | you inform other peers where the object code and Corresponding | ||
290 | Source of the work are being offered to the general public at no | ||
291 | charge under subsection 6d. | ||
292 | |||
293 | A separable portion of the object code, whose source code is excluded | ||
294 | from the Corresponding Source as a System Library, need not be | ||
295 | included in conveying the object code work. | ||
296 | |||
297 | A "User Product" is either (1) a "consumer product", which means any | ||
298 | tangible personal property which is normally used for personal, family, | ||
299 | or household purposes, or (2) anything designed or sold for incorporation | ||
300 | into a dwelling. In determining whether a product is a consumer product, | ||
301 | doubtful cases shall be resolved in favor of coverage. For a particular | ||
302 | product received by a particular user, "normally used" refers to a | ||
303 | typical or common use of that class of product, regardless of the status | ||
304 | of the particular user or of the way in which the particular user | ||
305 | actually uses, or expects or is expected to use, the product. A product | ||
306 | is a consumer product regardless of whether the product has substantial | ||
307 | commercial, industrial or non-consumer uses, unless such uses represent | ||
308 | the only significant mode of use of the product. | ||
309 | |||
310 | "Installation Information" for a User Product means any methods, | ||
311 | procedures, authorization keys, or other information required to install | ||
312 | and execute modified versions of a covered work in that User Product from | ||
313 | a modified version of its Corresponding Source. The information must | ||
314 | suffice to ensure that the continued functioning of the modified object | ||
315 | code is in no case prevented or interfered with solely because | ||
316 | modification has been made. | ||
317 | |||
318 | If you convey an object code work under this section in, or with, or | ||
319 | specifically for use in, a User Product, and the conveying occurs as | ||
320 | part of a transaction in which the right of possession and use of the | ||
321 | User Product is transferred to the recipient in perpetuity or for a | ||
322 | fixed term (regardless of how the transaction is characterized), the | ||
323 | Corresponding Source conveyed under this section must be accompanied | ||
324 | by the Installation Information. But this requirement does not apply | ||
325 | if neither you nor any third party retains the ability to install | ||
326 | modified object code on the User Product (for example, the work has | ||
327 | been installed in ROM). | ||
328 | |||
329 | The requirement to provide Installation Information does not include a | ||
330 | requirement to continue to provide support service, warranty, or updates | ||
331 | for a work that has been modified or installed by the recipient, or for | ||
332 | the User Product in which it has been modified or installed. Access to a | ||
333 | network may be denied when the modification itself materially and | ||
334 | adversely affects the operation of the network or violates the rules and | ||
335 | protocols for communication across the network. | ||
336 | |||
337 | Corresponding Source conveyed, and Installation Information provided, | ||
338 | in accord with this section must be in a format that is publicly | ||
339 | documented (and with an implementation available to the public in | ||
340 | source code form), and must require no special password or key for | ||
341 | unpacking, reading or copying. | ||
342 | |||
343 | 7. Additional Terms. | ||
344 | |||
345 | "Additional permissions" are terms that supplement the terms of this | ||
346 | License by making exceptions from one or more of its conditions. | ||
347 | Additional permissions that are applicable to the entire Program shall | ||
348 | be treated as though they were included in this License, to the extent | ||
349 | that they are valid under applicable law. If additional permissions | ||
350 | apply only to part of the Program, that part may be used separately | ||
351 | under those permissions, but the entire Program remains governed by | ||
352 | this License without regard to the additional permissions. | ||
353 | |||
354 | When you convey a copy of a covered work, you may at your option | ||
355 | remove any additional permissions from that copy, or from any part of | ||
356 | it. (Additional permissions may be written to require their own | ||
357 | removal in certain cases when you modify the work.) You may place | ||
358 | additional permissions on material, added by you to a covered work, | ||
359 | for which you have or can give appropriate copyright permission. | ||
360 | |||
361 | Notwithstanding any other provision of this License, for material you | ||
362 | add to a covered work, you may (if authorized by the copyright holders of | ||
363 | that material) supplement the terms of this License with terms: | ||
364 | |||
365 | a) Disclaiming warranty or limiting liability differently from the | ||
366 | terms of sections 15 and 16 of this License; or | ||
367 | |||
368 | b) Requiring preservation of specified reasonable legal notices or | ||
369 | author attributions in that material or in the Appropriate Legal | ||
370 | Notices displayed by works containing it; or | ||
371 | |||
372 | c) Prohibiting misrepresentation of the origin of that material, or | ||
373 | requiring that modified versions of such material be marked in | ||
374 | reasonable ways as different from the original version; or | ||
375 | |||
376 | d) Limiting the use for publicity purposes of names of licensors or | ||
377 | authors of the material; or | ||
378 | |||
379 | e) Declining to grant rights under trademark law for use of some | ||
380 | trade names, trademarks, or service marks; or | ||
381 | |||
382 | f) Requiring indemnification of licensors and authors of that | ||
383 | material by anyone who conveys the material (or modified versions of | ||
384 | it) with contractual assumptions of liability to the recipient, for | ||
385 | any liability that these contractual assumptions directly impose on | ||
386 | those licensors and authors. | ||
387 | |||
388 | All other non-permissive additional terms are considered "further | ||
389 | restrictions" within the meaning of section 10. If the Program as you | ||
390 | received it, or any part of it, contains a notice stating that it is | ||
391 | governed by this License along with a term that is a further | ||
392 | restriction, you may remove that term. If a license document contains | ||
393 | a further restriction but permits relicensing or conveying under this | ||
394 | License, you may add to a covered work material governed by the terms | ||
395 | of that license document, provided that the further restriction does | ||
396 | not survive such relicensing or conveying. | ||
397 | |||
398 | If you add terms to a covered work in accord with this section, you | ||
399 | must place, in the relevant source files, a statement of the | ||
400 | additional terms that apply to those files, or a notice indicating | ||
401 | where to find the applicable terms. | ||
402 | |||
403 | Additional terms, permissive or non-permissive, may be stated in the | ||
404 | form of a separately written license, or stated as exceptions; | ||
405 | the above requirements apply either way. | ||
406 | |||
407 | 8. Termination. | ||
408 | |||
409 | You may not propagate or modify a covered work except as expressly | ||
410 | provided under this License. Any attempt otherwise to propagate or | ||
411 | modify it is void, and will automatically terminate your rights under | ||
412 | this License (including any patent licenses granted under the third | ||
413 | paragraph of section 11). | ||
414 | |||
415 | However, if you cease all violation of this License, then your | ||
416 | license from a particular copyright holder is reinstated (a) | ||
417 | provisionally, unless and until the copyright holder explicitly and | ||
418 | finally terminates your license, and (b) permanently, if the copyright | ||
419 | holder fails to notify you of the violation by some reasonable means | ||
420 | prior to 60 days after the cessation. | ||
421 | |||
422 | Moreover, your license from a particular copyright holder is | ||
423 | reinstated permanently if the copyright holder notifies you of the | ||
424 | violation by some reasonable means, this is the first time you have | ||
425 | received notice of violation of this License (for any work) from that | ||
426 | copyright holder, and you cure the violation prior to 30 days after | ||
427 | your receipt of the notice. | ||
428 | |||
429 | Termination of your rights under this section does not terminate the | ||
430 | licenses of parties who have received copies or rights from you under | ||
431 | this License. If your rights have been terminated and not permanently | ||
432 | reinstated, you do not qualify to receive new licenses for the same | ||
433 | material under section 10. | ||
434 | |||
435 | 9. Acceptance Not Required for Having Copies. | ||
436 | |||
437 | You are not required to accept this License in order to receive or | ||
438 | run a copy of the Program. Ancillary propagation of a covered work | ||
439 | occurring solely as a consequence of using peer-to-peer transmission | ||
440 | to receive a copy likewise does not require acceptance. However, | ||
441 | nothing other than this License grants you permission to propagate or | ||
442 | modify any covered work. These actions infringe copyright if you do | ||
443 | not accept this License. Therefore, by modifying or propagating a | ||
444 | covered work, you indicate your acceptance of this License to do so. | ||
445 | |||
446 | 10. Automatic Licensing of Downstream Recipients. | ||
447 | |||
448 | Each time you convey a covered work, the recipient automatically | ||
449 | receives a license from the original licensors, to run, modify and | ||
450 | propagate that work, subject to this License. You are not responsible | ||
451 | for enforcing compliance by third parties with this License. | ||
452 | |||
453 | An "entity transaction" is a transaction transferring control of an | ||
454 | organization, or substantially all assets of one, or subdividing an | ||
455 | organization, or merging organizations. If propagation of a covered | ||
456 | work results from an entity transaction, each party to that | ||
457 | transaction who receives a copy of the work also receives whatever | ||
458 | licenses to the work the party's predecessor in interest had or could | ||
459 | give under the previous paragraph, plus a right to possession of the | ||
460 | Corresponding Source of the work from the predecessor in interest, if | ||
461 | the predecessor has it or can get it with reasonable efforts. | ||
462 | |||
463 | You may not impose any further restrictions on the exercise of the | ||
464 | rights granted or affirmed under this License. For example, you may | ||
465 | not impose a license fee, royalty, or other charge for exercise of | ||
466 | rights granted under this License, and you may not initiate litigation | ||
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that | ||
468 | any patent claim is infringed by making, using, selling, offering for | ||
469 | sale, or importing the Program or any portion of it. | ||
470 | |||
471 | 11. Patents. | ||
472 | |||
473 | A "contributor" is a copyright holder who authorizes use under this | ||
474 | License of the Program or a work on which the Program is based. The | ||
475 | work thus licensed is called the contributor's "contributor version". | ||
476 | |||
477 | A contributor's "essential patent claims" are all patent claims | ||
478 | owned or controlled by the contributor, whether already acquired or | ||
479 | hereafter acquired, that would be infringed by some manner, permitted | ||
480 | by this License, of making, using, or selling its contributor version, | ||
481 | but do not include claims that would be infringed only as a | ||
482 | consequence of further modification of the contributor version. For | ||
483 | purposes of this definition, "control" includes the right to grant | ||
484 | patent sublicenses in a manner consistent with the requirements of | ||
485 | this License. | ||
486 | |||
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free | ||
488 | patent license under the contributor's essential patent claims, to | ||
489 | make, use, sell, offer for sale, import and otherwise run, modify and | ||
490 | propagate the contents of its contributor version. | ||
491 | |||
492 | In the following three paragraphs, a "patent license" is any express | ||
493 | agreement or commitment, however denominated, not to enforce a patent | ||
494 | (such as an express permission to practice a patent or covenant not to | ||
495 | sue for patent infringement). To "grant" such a patent license to a | ||
496 | party means to make such an agreement or commitment not to enforce a | ||
497 | patent against the party. | ||
498 | |||
499 | If you convey a covered work, knowingly relying on a patent license, | ||
500 | and the Corresponding Source of the work is not available for anyone | ||
501 | to copy, free of charge and under the terms of this License, through a | ||
502 | publicly available network server or other readily accessible means, | ||
503 | then you must either (1) cause the Corresponding Source to be so | ||
504 | available, or (2) arrange to deprive yourself of the benefit of the | ||
505 | patent license for this particular work, or (3) arrange, in a manner | ||
506 | consistent with the requirements of this License, to extend the patent | ||
507 | license to downstream recipients. "Knowingly relying" means you have | ||
508 | actual knowledge that, but for the patent license, your conveying the | ||
509 | covered work in a country, or your recipient's use of the covered work | ||
510 | in a country, would infringe one or more identifiable patents in that | ||
511 | country that you have reason to believe are valid. | ||
512 | |||
513 | If, pursuant to or in connection with a single transaction or | ||
514 | arrangement, you convey, or propagate by procuring conveyance of, a | ||
515 | covered work, and grant a patent license to some of the parties | ||
516 | receiving the covered work authorizing them to use, propagate, modify | ||
517 | or convey a specific copy of the covered work, then the patent license | ||
518 | you grant is automatically extended to all recipients of the covered | ||
519 | work and works based on it. | ||
520 | |||
521 | A patent license is "discriminatory" if it does not include within | ||
522 | the scope of its coverage, prohibits the exercise of, or is | ||
523 | conditioned on the non-exercise of one or more of the rights that are | ||
524 | specifically granted under this License. You may not convey a covered | ||
525 | work if you are a party to an arrangement with a third party that is | ||
526 | in the business of distributing software, under which you make payment | ||
527 | to the third party based on the extent of your activity of conveying | ||
528 | the work, and under which the third party grants, to any of the | ||
529 | parties who would receive the covered work from you, a discriminatory | ||
530 | patent license (a) in connection with copies of the covered work | ||
531 | conveyed by you (or copies made from those copies), or (b) primarily | ||
532 | for and in connection with specific products or compilations that | ||
533 | contain the covered work, unless you entered into that arrangement, | ||
534 | or that patent license was granted, prior to 28 March 2007. | ||
535 | |||
536 | Nothing in this License shall be construed as excluding or limiting | ||
537 | any implied license or other defenses to infringement that may | ||
538 | otherwise be available to you under applicable patent law. | ||
539 | |||
540 | 12. No Surrender of Others' Freedom. | ||
541 | |||
542 | If conditions are imposed on you (whether by court order, agreement or | ||
543 | otherwise) that contradict the conditions of this License, they do not | ||
544 | excuse you from the conditions of this License. If you cannot convey a | ||
545 | covered work so as to satisfy simultaneously your obligations under this | ||
546 | License and any other pertinent obligations, then as a consequence you may | ||
547 | not convey it at all. For example, if you agree to terms that obligate you | ||
548 | to collect a royalty for further conveying from those to whom you convey | ||
549 | the Program, the only way you could satisfy both those terms and this | ||
550 | License would be to refrain entirely from conveying the Program. | ||
551 | |||
552 | 13. Use with the GNU Affero General Public License. | ||
553 | |||
554 | Notwithstanding any other provision of this License, you have | ||
555 | permission to link or combine any covered work with a work licensed | ||
556 | under version 3 of the GNU Affero General Public License into a single | ||
557 | combined work, and to convey the resulting work. The terms of this | ||
558 | License will continue to apply to the part which is the covered work, | ||
559 | but the special requirements of the GNU Affero General Public License, | ||
560 | section 13, concerning interaction through a network will apply to the | ||
561 | combination as such. | ||
562 | |||
563 | 14. Revised Versions of this License. | ||
564 | |||
565 | The Free Software Foundation may publish revised and/or new versions of | ||
566 | the GNU General Public License from time to time. Such new versions will | ||
567 | be similar in spirit to the present version, but may differ in detail to | ||
568 | address new problems or concerns. | ||
569 | |||
570 | Each version is given a distinguishing version number. If the | ||
571 | Program specifies that a certain numbered version of the GNU General | ||
572 | Public License "or any later version" applies to it, you have the | ||
573 | option of following the terms and conditions either of that numbered | ||
574 | version or of any later version published by the Free Software | ||
575 | Foundation. If the Program does not specify a version number of the | ||
576 | GNU General Public License, you may choose any version ever published | ||
577 | by the Free Software Foundation. | ||
578 | |||
579 | If the Program specifies that a proxy can decide which future | ||
580 | versions of the GNU General Public License can be used, that proxy's | ||
581 | public statement of acceptance of a version permanently authorizes you | ||
582 | to choose that version for the Program. | ||
583 | |||
584 | Later license versions may give you additional or different | ||
585 | permissions. However, no additional obligations are imposed on any | ||
586 | author or copyright holder as a result of your choosing to follow a | ||
587 | later version. | ||
588 | |||
589 | 15. Disclaimer of Warranty. | ||
590 | |||
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | ||
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | ||
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | ||
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | ||
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | ||
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | ||
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | ||
599 | |||
600 | 16. Limitation of Liability. | ||
601 | |||
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | ||
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | ||
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | ||
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | ||
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | ||
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | ||
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | ||
610 | SUCH DAMAGES. | ||
611 | |||
612 | 17. Interpretation of Sections 15 and 16. | ||
613 | |||
614 | If the disclaimer of warranty and limitation of liability provided | ||
615 | above cannot be given local legal effect according to their terms, | ||
616 | reviewing courts shall apply local law that most closely approximates | ||
617 | an absolute waiver of all civil liability in connection with the | ||
618 | Program, unless a warranty or assumption of liability accompanies a | ||
619 | copy of the Program in return for a fee. | ||
620 | |||
621 | END OF TERMS AND CONDITIONS | ||
622 | |||
623 | How to Apply These Terms to Your New Programs | ||
624 | |||
625 | If you develop a new program, and you want it to be of the greatest | ||
626 | possible use to the public, the best way to achieve this is to make it | ||
627 | free software which everyone can redistribute and change under these terms. | ||
628 | |||
629 | To do so, attach the following notices to the program. It is safest | ||
630 | to attach them to the start of each source file to most effectively | ||
631 | state the exclusion of warranty; and each file should have at least | ||
632 | the "copyright" line and a pointer to where the full notice is found. | ||
633 | |||
634 | <one line to give the program's name and a brief idea of what it does.> | ||
635 | Copyright (C) <year> <name of author> | ||
636 | |||
637 | This program is free software: you can redistribute it and/or modify | ||
638 | it under the terms of the GNU General Public License as published by | ||
639 | the Free Software Foundation, either version 3 of the License, or | ||
640 | (at your option) any later version. | ||
641 | |||
642 | This program is distributed in the hope that it will be useful, | ||
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
645 | GNU General Public License for more details. | ||
646 | |||
647 | You should have received a copy of the GNU General Public License | ||
648 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
649 | |||
650 | Also add information on how to contact you by electronic and paper mail. | ||
651 | |||
652 | If the program does terminal interaction, make it output a short | ||
653 | notice like this when it starts in an interactive mode: | ||
654 | |||
655 | <program> Copyright (C) <year> <name of author> | ||
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||
657 | This is free software, and you are welcome to redistribute it | ||
658 | under certain conditions; type `show c' for details. | ||
659 | |||
660 | The hypothetical commands `show w' and `show c' should show the appropriate | ||
661 | parts of the General Public License. Of course, your program's commands | ||
662 | might be different; for a GUI interface, you would use an "about box". | ||
663 | |||
664 | You should also get your employer (if you work as a programmer) or school, | ||
665 | if any, to sign a "copyright disclaimer" for the program, if necessary. | ||
666 | For more information on this, and how to apply and follow the GNU GPL, see | ||
667 | <http://www.gnu.org/licenses/>. | ||
668 | |||
669 | The GNU General Public License does not permit incorporating your program | ||
670 | into proprietary programs. If your program is a subroutine library, you | ||
671 | may consider it more useful to permit linking proprietary applications with | ||
672 | the library. If this is what you want to do, use the GNU Lesser General | ||
673 | Public License instead of this License. But first, please read | ||
674 | <http://www.gnu.org/philosophy/why-not-lgpl.html>. | ||
diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog | |||
@@ -0,0 +1,370 @@ | |||
1 | Installation Instructions | ||
2 | ************************* | ||
3 | |||
4 | Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, | ||
5 | Inc. | ||
6 | |||
7 | Copying and distribution of this file, with or without modification, | ||
8 | are permitted in any medium without royalty provided the copyright | ||
9 | notice and this notice are preserved. This file is offered as-is, | ||
10 | without warranty of any kind. | ||
11 | |||
12 | Basic Installation | ||
13 | ================== | ||
14 | |||
15 | Briefly, the shell commands `./configure; make; make install' should | ||
16 | configure, build, and install this package. The following | ||
17 | more-detailed instructions are generic; see the `README' file for | ||
18 | instructions specific to this package. Some packages provide this | ||
19 | `INSTALL' file but do not implement all of the features documented | ||
20 | below. The lack of an optional feature in a given package is not | ||
21 | necessarily a bug. More recommendations for GNU packages can be found | ||
22 | in *note Makefile Conventions: (standards)Makefile Conventions. | ||
23 | |||
24 | The `configure' shell script attempts to guess correct values for | ||
25 | various system-dependent variables used during compilation. It uses | ||
26 | those values to create a `Makefile' in each directory of the package. | ||
27 | It may also create one or more `.h' files containing system-dependent | ||
28 | definitions. Finally, it creates a shell script `config.status' that | ||
29 | you can run in the future to recreate the current configuration, and a | ||
30 | file `config.log' containing compiler output (useful mainly for | ||
31 | debugging `configure'). | ||
32 | |||
33 | It can also use an optional file (typically called `config.cache' | ||
34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves | ||
35 | the results of its tests to speed up reconfiguring. Caching is | ||
36 | disabled by default to prevent problems with accidental use of stale | ||
37 | cache files. | ||
38 | |||
39 | If you need to do unusual things to compile the package, please try | ||
40 | to figure out how `configure' could check whether to do them, and mail | ||
41 | diffs or instructions to the address given in the `README' so they can | ||
42 | be considered for the next release. If you are using the cache, and at | ||
43 | some point `config.cache' contains results you don't want to keep, you | ||
44 | may remove or edit it. | ||
45 | |||
46 | The file `configure.ac' (or `configure.in') is used to create | ||
47 | `configure' by a program called `autoconf'. You need `configure.ac' if | ||
48 | you want to change it or regenerate `configure' using a newer version | ||
49 | of `autoconf'. | ||
50 | |||
51 | The simplest way to compile this package is: | ||
52 | |||
53 | 1. `cd' to the directory containing the package's source code and type | ||
54 | `./configure' to configure the package for your system. | ||
55 | |||
56 | Running `configure' might take a while. While running, it prints | ||
57 | some messages telling which features it is checking for. | ||
58 | |||
59 | 2. Type `make' to compile the package. | ||
60 | |||
61 | 3. Optionally, type `make check' to run any self-tests that come with | ||
62 | the package, generally using the just-built uninstalled binaries. | ||
63 | |||
64 | 4. Type `make install' to install the programs and any data files and | ||
65 | documentation. When installing into a prefix owned by root, it is | ||
66 | recommended that the package be configured and built as a regular | ||
67 | user, and only the `make install' phase executed with root | ||
68 | privileges. | ||
69 | |||
70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but | ||
71 | this time using the binaries in their final installed location. | ||
72 | This target does not install anything. Running this target as a | ||
73 | regular user, particularly if the prior `make install' required | ||
74 | root privileges, verifies that the installation completed | ||
75 | correctly. | ||
76 | |||
77 | 6. You can remove the program binaries and object files from the | ||
78 | source code directory by typing `make clean'. To also remove the | ||
79 | files that `configure' created (so you can compile the package for | ||
80 | a different kind of computer), type `make distclean'. There is | ||
81 | also a `make maintainer-clean' target, but that is intended mainly | ||
82 | for the package's developers. If you use it, you may have to get | ||
83 | all sorts of other programs in order to regenerate files that came | ||
84 | with the distribution. | ||
85 | |||
86 | 7. Often, you can also type `make uninstall' to remove the installed | ||
87 | files again. In practice, not all packages have tested that | ||
88 | uninstallation works correctly, even though it is required by the | ||
89 | GNU Coding Standards. | ||
90 | |||
91 | 8. Some packages, particularly those that use Automake, provide `make | ||
92 | distcheck', which can by used by developers to test that all other | ||
93 | targets like `make install' and `make uninstall' work correctly. | ||
94 | This target is generally not run by end users. | ||
95 | |||
96 | Compilers and Options | ||
97 | ===================== | ||
98 | |||
99 | Some systems require unusual options for compilation or linking that | ||
100 | the `configure' script does not know about. Run `./configure --help' | ||
101 | for details on some of the pertinent environment variables. | ||
102 | |||
103 | You can give `configure' initial values for configuration parameters | ||
104 | by setting variables in the command line or in the environment. Here | ||
105 | is an example: | ||
106 | |||
107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix | ||
108 | |||
109 | *Note Defining Variables::, for more details. | ||
110 | |||
111 | Compiling For Multiple Architectures | ||
112 | ==================================== | ||
113 | |||
114 | You can compile the package for more than one kind of computer at the | ||
115 | same time, by placing the object files for each architecture in their | ||
116 | own directory. To do this, you can use GNU `make'. `cd' to the | ||
117 | directory where you want the object files and executables to go and run | ||
118 | the `configure' script. `configure' automatically checks for the | ||
119 | source code in the directory that `configure' is in and in `..'. This | ||
120 | is known as a "VPATH" build. | ||
121 | |||
122 | With a non-GNU `make', it is safer to compile the package for one | ||
123 | architecture at a time in the source code directory. After you have | ||
124 | installed the package for one architecture, use `make distclean' before | ||
125 | reconfiguring for another architecture. | ||
126 | |||
127 | On MacOS X 10.5 and later systems, you can create libraries and | ||
128 | executables that work on multiple system types--known as "fat" or | ||
129 | "universal" binaries--by specifying multiple `-arch' options to the | ||
130 | compiler but only a single `-arch' option to the preprocessor. Like | ||
131 | this: | ||
132 | |||
133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ | ||
134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ | ||
135 | CPP="gcc -E" CXXCPP="g++ -E" | ||
136 | |||
137 | This is not guaranteed to produce working output in all cases, you | ||
138 | may have to build one architecture at a time and combine the results | ||
139 | using the `lipo' tool if you have problems. | ||
140 | |||
141 | Installation Names | ||
142 | ================== | ||
143 | |||
144 | By default, `make install' installs the package's commands under | ||
145 | `/usr/local/bin', include files under `/usr/local/include', etc. You | ||
146 | can specify an installation prefix other than `/usr/local' by giving | ||
147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an | ||
148 | absolute file name. | ||
149 | |||
150 | You can specify separate installation prefixes for | ||
151 | architecture-specific files and architecture-independent files. If you | ||
152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses | ||
153 | PREFIX as the prefix for installing programs and libraries. | ||
154 | Documentation and other data files still use the regular prefix. | ||
155 | |||
156 | In addition, if you use an unusual directory layout you can give | ||
157 | options like `--bindir=DIR' to specify different values for particular | ||
158 | kinds of files. Run `configure --help' for a list of the directories | ||
159 | you can set and what kinds of files go in them. In general, the | ||
160 | default for these options is expressed in terms of `${prefix}', so that | ||
161 | specifying just `--prefix' will affect all of the other directory | ||
162 | specifications that were not explicitly provided. | ||
163 | |||
164 | The most portable way to affect installation locations is to pass the | ||
165 | correct locations to `configure'; however, many packages provide one or | ||
166 | both of the following shortcuts of passing variable assignments to the | ||
167 | `make install' command line to change installation locations without | ||
168 | having to reconfigure or recompile. | ||
169 | |||
170 | The first method involves providing an override variable for each | ||
171 | affected directory. For example, `make install | ||
172 | prefix=/alternate/directory' will choose an alternate location for all | ||
173 | directory configuration variables that were expressed in terms of | ||
174 | `${prefix}'. Any directories that were specified during `configure', | ||
175 | but not in terms of `${prefix}', must each be overridden at install | ||
176 | time for the entire installation to be relocated. The approach of | ||
177 | makefile variable overrides for each directory variable is required by | ||
178 | the GNU Coding Standards, and ideally causes no recompilation. | ||
179 | However, some platforms have known limitations with the semantics of | ||
180 | shared libraries that end up requiring recompilation when using this | ||
181 | method, particularly noticeable in packages that use GNU Libtool. | ||
182 | |||
183 | The second method involves providing the `DESTDIR' variable. For | ||
184 | example, `make install DESTDIR=/alternate/directory' will prepend | ||
185 | `/alternate/directory' before all installation names. The approach of | ||
186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and | ||
187 | does not work on platforms that have drive letters. On the other hand, | ||
188 | it does better at avoiding recompilation issues, and works well even | ||
189 | when some directory options were not specified in terms of `${prefix}' | ||
190 | at `configure' time. | ||
191 | |||
192 | Optional Features | ||
193 | ================= | ||
194 | |||
195 | If the package supports it, you can cause programs to be installed | ||
196 | with an extra prefix or suffix on their names by giving `configure' the | ||
197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. | ||
198 | |||
199 | Some packages pay attention to `--enable-FEATURE' options to | ||
200 | `configure', where FEATURE indicates an optional part of the package. | ||
201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE | ||
202 | is something like `gnu-as' or `x' (for the X Window System). The | ||
203 | `README' should mention any `--enable-' and `--with-' options that the | ||
204 | package recognizes. | ||
205 | |||
206 | For packages that use the X Window System, `configure' can usually | ||
207 | find the X include and library files automatically, but if it doesn't, | ||
208 | you can use the `configure' options `--x-includes=DIR' and | ||
209 | `--x-libraries=DIR' to specify their locations. | ||
210 | |||
211 | Some packages offer the ability to configure how verbose the | ||
212 | execution of `make' will be. For these packages, running `./configure | ||
213 | --enable-silent-rules' sets the default to minimal output, which can be | ||
214 | overridden with `make V=1'; while running `./configure | ||
215 | --disable-silent-rules' sets the default to verbose, which can be | ||
216 | overridden with `make V=0'. | ||
217 | |||
218 | Particular systems | ||
219 | ================== | ||
220 | |||
221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU | ||
222 | CC is not installed, it is recommended to use the following options in | ||
223 | order to use an ANSI C compiler: | ||
224 | |||
225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" | ||
226 | |||
227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. | ||
228 | |||
229 | HP-UX `make' updates targets which have the same time stamps as | ||
230 | their prerequisites, which makes it generally unusable when shipped | ||
231 | generated files such as `configure' are involved. Use GNU `make' | ||
232 | instead. | ||
233 | |||
234 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot | ||
235 | parse its `<wchar.h>' header file. The option `-nodtk' can be used as | ||
236 | a workaround. If GNU CC is not installed, it is therefore recommended | ||
237 | to try | ||
238 | |||
239 | ./configure CC="cc" | ||
240 | |||
241 | and if that doesn't work, try | ||
242 | |||
243 | ./configure CC="cc -nodtk" | ||
244 | |||
245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This | ||
246 | directory contains several dysfunctional programs; working variants of | ||
247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' | ||
248 | in your `PATH', put it _after_ `/usr/bin'. | ||
249 | |||
250 | On Haiku, software installed for all users goes in `/boot/common', | ||
251 | not `/usr/local'. It is recommended to use the following options: | ||
252 | |||
253 | ./configure --prefix=/boot/common | ||
254 | |||
255 | Specifying the System Type | ||
256 | ========================== | ||
257 | |||
258 | There may be some features `configure' cannot figure out | ||
259 | automatically, but needs to determine by the type of machine the package | ||
260 | will run on. Usually, assuming the package is built to be run on the | ||
261 | _same_ architectures, `configure' can figure that out, but if it prints | ||
262 | a message saying it cannot guess the machine type, give it the | ||
263 | `--build=TYPE' option. TYPE can either be a short name for the system | ||
264 | type, such as `sun4', or a canonical name which has the form: | ||
265 | |||
266 | CPU-COMPANY-SYSTEM | ||
267 | |||
268 | where SYSTEM can have one of these forms: | ||
269 | |||
270 | OS | ||
271 | KERNEL-OS | ||
272 | |||
273 | See the file `config.sub' for the possible values of each field. If | ||
274 | `config.sub' isn't included in this package, then this package doesn't | ||
275 | need to know the machine type. | ||
276 | |||
277 | If you are _building_ compiler tools for cross-compiling, you should | ||
278 | use the option `--target=TYPE' to select the type of system they will | ||
279 | produce code for. | ||
280 | |||
281 | If you want to _use_ a cross compiler, that generates code for a | ||
282 | platform different from the build platform, you should specify the | ||
283 | "host" platform (i.e., that on which the generated programs will | ||
284 | eventually be run) with `--host=TYPE'. | ||
285 | |||
286 | Sharing Defaults | ||
287 | ================ | ||
288 | |||
289 | If you want to set default values for `configure' scripts to share, | ||
290 | you can create a site shell script called `config.site' that gives | ||
291 | default values for variables like `CC', `cache_file', and `prefix'. | ||
292 | `configure' looks for `PREFIX/share/config.site' if it exists, then | ||
293 | `PREFIX/etc/config.site' if it exists. Or, you can set the | ||
294 | `CONFIG_SITE' environment variable to the location of the site script. | ||
295 | A warning: not all `configure' scripts look for a site script. | ||
296 | |||
297 | Defining Variables | ||
298 | ================== | ||
299 | |||
300 | Variables not defined in a site shell script can be set in the | ||
301 | environment passed to `configure'. However, some packages may run | ||
302 | configure again during the build, and the customized values of these | ||
303 | variables may be lost. In order to avoid this problem, you should set | ||
304 | them in the `configure' command line, using `VAR=value'. For example: | ||
305 | |||
306 | ./configure CC=/usr/local2/bin/gcc | ||
307 | |||
308 | causes the specified `gcc' to be used as the C compiler (unless it is | ||
309 | overridden in the site shell script). | ||
310 | |||
311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to | ||
312 | an Autoconf limitation. Until the limitation is lifted, you can use | ||
313 | this workaround: | ||
314 | |||
315 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash | ||
316 | |||
317 | `configure' Invocation | ||
318 | ====================== | ||
319 | |||
320 | `configure' recognizes the following options to control how it | ||
321 | operates. | ||
322 | |||
323 | `--help' | ||
324 | `-h' | ||
325 | Print a summary of all of the options to `configure', and exit. | ||
326 | |||
327 | `--help=short' | ||
328 | `--help=recursive' | ||
329 | Print a summary of the options unique to this package's | ||
330 | `configure', and exit. The `short' variant lists options used | ||
331 | only in the top level, while the `recursive' variant lists options | ||
332 | also present in any nested packages. | ||
333 | |||
334 | `--version' | ||
335 | `-V' | ||
336 | Print the version of Autoconf used to generate the `configure' | ||
337 | script, and exit. | ||
338 | |||
339 | `--cache-file=FILE' | ||
340 | Enable the cache: use and save the results of the tests in FILE, | ||
341 | traditionally `config.cache'. FILE defaults to `/dev/null' to | ||
342 | disable caching. | ||
343 | |||
344 | `--config-cache' | ||
345 | `-C' | ||
346 | Alias for `--cache-file=config.cache'. | ||
347 | |||
348 | `--quiet' | ||
349 | `--silent' | ||
350 | `-q' | ||
351 | Do not print messages saying which checks are being made. To | ||
352 | suppress all normal output, redirect it to `/dev/null' (any error | ||
353 | messages will still be shown). | ||
354 | |||
355 | `--srcdir=DIR' | ||
356 | Look for the package's source code in directory DIR. Usually | ||
357 | `configure' can determine that directory automatically. | ||
358 | |||
359 | `--prefix=DIR' | ||
360 | Use DIR as the installation prefix. *note Installation Names:: | ||
361 | for more details, including other options available for fine-tuning | ||
362 | the installation locations. | ||
363 | |||
364 | `--no-create' | ||
365 | `-n' | ||
366 | Run the configure checks, but stop before creating any output | ||
367 | files. | ||
368 | |||
369 | `configure' also accepts some other, not widely useful, options. Run | ||
370 | `configure --help' for more details. | ||
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..e2b7d09 --- /dev/null +++ b/Makefile.am | |||
@@ -0,0 +1,5 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | SUBDIRS = src | ||
3 | |||
4 | ACLOCAL_AMFLAGS = -I m4 | ||
5 | |||
@@ -0,0 +1,48 @@ | |||
1 | ## gnunet-dbus: A DBus proxy for GNUnet | ||
2 | |||
3 | # Purpose | ||
4 | |||
5 | The aim of this project is to make it easy to control GNUnet via DBus. Any | ||
6 | DBus-enabled piece of software should be able to use this to start/stop GNUnet | ||
7 | services, perform GNS lookups, download files etc. | ||
8 | |||
9 | # Installation | ||
10 | |||
11 | $ ./bootstrap | ||
12 | $ ./configure | ||
13 | $ make | ||
14 | $ make install | ||
15 | |||
16 | After that, you will need to relax the DBus permissions to allow gnunet-dbus to | ||
17 | use the system bus. On most Linux distros, copying src/etc/gnunet-dbus.conf to | ||
18 | /etc/dbus-1/system.d/ should do the trick. Otherwise, you can use that file for | ||
19 | guidance on how to setup permissions. | ||
20 | |||
21 | # Running | ||
22 | |||
23 | gnunet-dbus is not currently integrated with gnunet-arm or any init system so | ||
24 | you'll have to run the binaries manually. There is one gnunet-dbus executable | ||
25 | per GNUnet service. They are installed to $PREFIX/bin by default and have names | ||
26 | like gnunet-service-dht-dbus, gnunet-service-gns-dbus etc. | ||
27 | |||
28 | # Hacking | ||
29 | |||
30 | Contributions are welcome! | ||
31 | |||
32 | In the src/ directory you'll find the service/ and lib/ directories. service/ | ||
33 | contains the source for the service executables (gnunet-service-gns-dbus etc.). | ||
34 | lib/ contains all the source and headers for the gnunet-dbus libraries. | ||
35 | lib/common/ is probably the most interesting directory here as it contains the | ||
36 | bulk of the code for binding libdbus with GNUnet's event loop. The other | ||
37 | directories in lib/ mainly consist of code for serialising/deserialising types | ||
38 | from the various parts of GNUnet's API. | ||
39 | |||
40 | For learning how to use this library to write more service wrappers or extend | ||
41 | the existing ones it's probably easiest to read through existing code. The code | ||
42 | tries to be clear and logical and is very object-oriented. | ||
43 | gnunet-service-gns-dbus.c shows, for example, how to setup a dbus | ||
44 | service+object+interface+method for performing lookups and bind this DBus | ||
45 | method to an internal function which calls GNUNET_GNS_lookup. All types and | ||
46 | functions exposed by the library side of gnunet-dbus are documented in the | ||
47 | header files in src/lib/include | ||
48 | |||
diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..a28bc75 --- /dev/null +++ b/bootstrap | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | autoreconf --install | ||
4 | |||
diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f3381be --- /dev/null +++ b/configure.ac | |||
@@ -0,0 +1,27 @@ | |||
1 | AC_INIT([gnunet-dbus],[0.10.0],[shum@canndrew.org]) | ||
2 | AM_INIT_AUTOMAKE([-Wall -Werror]) | ||
3 | AC_CONFIG_MACRO_DIR([m4]) | ||
4 | AC_PROG_CC | ||
5 | AM_PROG_AR | ||
6 | LT_INIT([disable-static dlopen win32-dll]) | ||
7 | AC_CONFIG_HEADERS([config.h]) | ||
8 | AC_CONFIG_FILES([ | ||
9 | Makefile | ||
10 | src/Makefile | ||
11 | src/lib/Makefile | ||
12 | src/lib/common/Makefile | ||
13 | src/lib/block/Makefile | ||
14 | src/lib/dht/Makefile | ||
15 | src/lib/gnsrecord/Makefile | ||
16 | src/lib/util/Makefile | ||
17 | src/services/Makefile | ||
18 | ]) | ||
19 | |||
20 | PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.6.8]) | ||
21 | |||
22 | CFLAGS="$CFLAGS -Wall -Werror" | ||
23 | CFLAGS="$CFLAGS $DBUS_CFLAGS" | ||
24 | LDFLAGS="$LDFLAGS $DBUS_LDFLAGS" | ||
25 | |||
26 | AC_OUTPUT | ||
27 | |||
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..93829dd --- /dev/null +++ b/src/Makefile.am | |||
@@ -0,0 +1,3 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | SUBDIRS = lib services | ||
3 | |||
diff --git a/src/etc/gnunet-dbus.conf b/src/etc/gnunet-dbus.conf new file mode 100644 index 0000000..5cbc34a --- /dev/null +++ b/src/etc/gnunet-dbus.conf | |||
@@ -0,0 +1,20 @@ | |||
1 | <!DOCTYPE busconfig PUBLIC | ||
2 | "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" | ||
3 | "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> | ||
4 | <busconfig> | ||
5 | <policy group="gnunet"> | ||
6 | <allow own_prefix="gnu.gnunet"/> | ||
7 | <allow send_destination="gnu.gnunet.dht"/> | ||
8 | <allow receive_sender="gnu.gnunet.dht"/> | ||
9 | <allow send_destination="gnu.gnunet.gns"/> | ||
10 | <allow receive_sender="gnu.gnunet.gns"/> | ||
11 | </policy> | ||
12 | <policy user="root"> | ||
13 | <allow own_prefix="gnu.gnunet"/> | ||
14 | <allow send_destination="gnu.gnunet.dht"/> | ||
15 | <allow receive_sender="gnu.gnunet.dht"/> | ||
16 | <allow send_destination="gnu.gnunet.gns"/> | ||
17 | <allow receive_sender="gnu.gnunet.gns"/> | ||
18 | </policy> | ||
19 | </busconfig> | ||
20 | |||
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am new file mode 100644 index 0000000..594cb3a --- /dev/null +++ b/src/lib/Makefile.am | |||
@@ -0,0 +1,3 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | SUBDIRS = common block dht util gnsrecord | ||
3 | |||
diff --git a/src/lib/block/Makefile.am b/src/lib/block/Makefile.am new file mode 100644 index 0000000..b3af878 --- /dev/null +++ b/src/lib/block/Makefile.am | |||
@@ -0,0 +1,16 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | lib_LTLIBRARIES = \ | ||
3 | libgnunetblockdbus.la | ||
4 | |||
5 | libgnunetblockdbus_la_SOURCES = \ | ||
6 | gnunet_block_dbus_lib.c \ | ||
7 | gnunet_block_dbus_lib_pop.c \ | ||
8 | gnunet_block_dbus_lib_push.c | ||
9 | |||
10 | libgnunetblockdbus_la_CFLAGS = \ | ||
11 | -I$(top_builddir)/src/lib/include \ | ||
12 | $(DBUS_CFLAGS) | ||
13 | |||
14 | libgnunetblockdbus_la_LDFLAGS = \ | ||
15 | $(DBUS_LIBS) | ||
16 | |||
diff --git a/src/lib/block/gnunet_block_dbus_lib.c b/src/lib/block/gnunet_block_dbus_lib.c new file mode 100644 index 0000000..c0e52fe --- /dev/null +++ b/src/lib/block/gnunet_block_dbus_lib.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_block_lib.h> | ||
6 | |||
7 | #include "gnunet_block_dbus_lib.h" | ||
8 | |||
9 | const struct GNUNET_DBUS_StringEnumPair GNUNET_BLOCK_DBUS_type_description[] = { | ||
10 | {"any", GNUNET_BLOCK_TYPE_ANY}, | ||
11 | {"fs_dblock", GNUNET_BLOCK_TYPE_FS_DBLOCK}, | ||
12 | {"fs_iblock", GNUNET_BLOCK_TYPE_FS_IBLOCK}, | ||
13 | {"fs_kblock", GNUNET_BLOCK_TYPE_FS_KBLOCK}, | ||
14 | {"fs_sblock", GNUNET_BLOCK_TYPE_FS_SBLOCK}, | ||
15 | {"fs_nblock", GNUNET_BLOCK_TYPE_FS_NBLOCK}, | ||
16 | {"fs_ondemand", GNUNET_BLOCK_TYPE_FS_ONDEMAND}, | ||
17 | {"dht_hello", GNUNET_BLOCK_TYPE_DHT_HELLO}, | ||
18 | {"test", GNUNET_BLOCK_TYPE_TEST}, | ||
19 | {"fs_ublock", GNUNET_BLOCK_TYPE_FS_UBLOCK}, | ||
20 | {"dns", GNUNET_BLOCK_TYPE_DNS}, | ||
21 | {"gns_namerecord", GNUNET_BLOCK_TYPE_GNS_NAMERECORD}, | ||
22 | {"regex", GNUNET_BLOCK_TYPE_REGEX}, | ||
23 | {"regex_accept", GNUNET_BLOCK_TYPE_REGEX_ACCEPT}, | ||
24 | {NULL, 0} | ||
25 | }; | ||
26 | |||
diff --git a/src/lib/block/gnunet_block_dbus_lib_pop.c b/src/lib/block/gnunet_block_dbus_lib_pop.c new file mode 100644 index 0000000..8323495 --- /dev/null +++ b/src/lib/block/gnunet_block_dbus_lib_pop.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_block_lib.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib.h" | ||
8 | #include "gnunet_block_dbus_lib.h" | ||
9 | |||
10 | DBusMessage * | ||
11 | GNUNET_BLOCK_DBUS_pop_type ( | ||
12 | DBusMessage *message, | ||
13 | DBusMessageIter *iter, | ||
14 | const char *arg_name, | ||
15 | enum GNUNET_BLOCK_Type *value) | ||
16 | { | ||
17 | return GNUNET_DBUS_pop_enum (message, iter, arg_name, (int *)value, GNUNET_BLOCK_DBUS_type_description); | ||
18 | }; | ||
19 | |||
20 | |||
diff --git a/src/lib/block/gnunet_block_dbus_lib_push.c b/src/lib/block/gnunet_block_dbus_lib_push.c new file mode 100644 index 0000000..1aaca01 --- /dev/null +++ b/src/lib/block/gnunet_block_dbus_lib_push.c | |||
@@ -0,0 +1,18 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_block_lib.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib.h" | ||
8 | #include "gnunet_block_dbus_lib.h" | ||
9 | |||
10 | void | ||
11 | GNUNET_BLOCK_DBUS_push_type ( | ||
12 | DBusMessage *message, | ||
13 | DBusMessageIter *iter, | ||
14 | const enum GNUNET_BLOCK_Type *value) | ||
15 | { | ||
16 | return GNUNET_DBUS_push_enum (message, iter, (const int *)value, GNUNET_BLOCK_DBUS_type_description); | ||
17 | }; | ||
18 | |||
diff --git a/src/lib/common/Makefile.am b/src/lib/common/Makefile.am new file mode 100644 index 0000000..04f1489 --- /dev/null +++ b/src/lib/common/Makefile.am | |||
@@ -0,0 +1,31 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CFLAGS = \ | ||
3 | -I$(top_builddir)/src/lib/include | ||
4 | |||
5 | lib_LTLIBRARIES = \ | ||
6 | libgnunetdbus.la | ||
7 | |||
8 | libgnunetdbus_la_SOURCES = \ | ||
9 | watch.c \ | ||
10 | timeout.c \ | ||
11 | gnunet_dbus_lib_service.c \ | ||
12 | gnunet_dbus_lib_object.c \ | ||
13 | gnunet_dbus_lib_object_path.c \ | ||
14 | gnunet_dbus_lib_interface.c \ | ||
15 | gnunet_dbus_lib_method.c \ | ||
16 | gnunet_dbus_lib_signal.c \ | ||
17 | gnunet_dbus_lib_arg.c \ | ||
18 | gnunet_dbus_lib_message.c \ | ||
19 | gnunet_dbus_lib_method_context.c \ | ||
20 | gnunet_dbus_lib_pop.c \ | ||
21 | gnunet_dbus_lib_push.c \ | ||
22 | gnunet_dbus_lib_client.c \ | ||
23 | gnunet_dbus_lib_signature.c | ||
24 | |||
25 | libgnunetdbus_la_CFLAGS = \ | ||
26 | -I$(top_builddir)/src/lib/include \ | ||
27 | $(DBUS_CFLAGS) | ||
28 | |||
29 | libgnunetdbus_la_LDFLAGS = \ | ||
30 | $(DBUS_LIBS) | ||
31 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_arg.c b/src/lib/common/gnunet_dbus_lib_arg.c new file mode 100644 index 0000000..a6be456 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_arg.c | |||
@@ -0,0 +1,65 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | |||
6 | #include "gnunet_dbus_lib.h" | ||
7 | |||
8 | #define LOG(kind, ...) GNUNET_log_from(kind, "dbus-arg", __VA_ARGS__) | ||
9 | |||
10 | struct GNUNET_DBUS_Arg | ||
11 | { | ||
12 | char *name; | ||
13 | const char *signature; | ||
14 | unsigned ref_count; | ||
15 | }; | ||
16 | |||
17 | struct GNUNET_DBUS_Arg * | ||
18 | GNUNET_DBUS_arg_create ( | ||
19 | const char *name, | ||
20 | const char *signature) | ||
21 | { | ||
22 | struct GNUNET_DBUS_Arg *arg = GNUNET_new (struct GNUNET_DBUS_Arg); | ||
23 | arg->name = GNUNET_strdup (name); | ||
24 | arg->signature = signature; | ||
25 | arg->ref_count = 1; | ||
26 | return arg; | ||
27 | }; | ||
28 | |||
29 | void | ||
30 | GNUNET_DBUS_arg_ref ( | ||
31 | struct GNUNET_DBUS_Arg *arg) | ||
32 | { | ||
33 | arg->ref_count++; | ||
34 | }; | ||
35 | |||
36 | void | ||
37 | GNUNET_DBUS_arg_unref ( | ||
38 | struct GNUNET_DBUS_Arg *arg) | ||
39 | { | ||
40 | if (arg->ref_count == 0) | ||
41 | { | ||
42 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference arg with ref count 0\n"); | ||
43 | GNUNET_abort_ (); | ||
44 | }; | ||
45 | if (0 == --(arg->ref_count)) | ||
46 | { | ||
47 | GNUNET_free (arg->name); | ||
48 | GNUNET_free (arg); | ||
49 | }; | ||
50 | }; | ||
51 | |||
52 | const char * | ||
53 | GNUNET_DBUS_arg_get_name ( | ||
54 | const struct GNUNET_DBUS_Arg *arg) | ||
55 | { | ||
56 | return arg->name; | ||
57 | }; | ||
58 | |||
59 | const char * | ||
60 | GNUNET_DBUS_arg_get_signature ( | ||
61 | const struct GNUNET_DBUS_Arg *arg) | ||
62 | { | ||
63 | return arg->signature; | ||
64 | }; | ||
65 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_client.c b/src/lib/common/gnunet_dbus_lib_client.c new file mode 100644 index 0000000..72b3aef --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_client.c | |||
@@ -0,0 +1,119 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | |||
6 | #include "gnunet_dbus_lib.h" | ||
7 | |||
8 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-client", __VA_ARGS__) | ||
9 | |||
10 | struct GNUNET_DBUS_Client | ||
11 | { | ||
12 | char *unique_name; | ||
13 | void *data; | ||
14 | bool prefers_pretty_encodings; | ||
15 | unsigned ref_count; | ||
16 | }; | ||
17 | |||
18 | struct GNUNET_DBUS_Client * | ||
19 | GNUNET_DBUS_client_create ( | ||
20 | const char *unique_name) | ||
21 | { | ||
22 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating client with unique name %s\n", unique_name); | ||
23 | |||
24 | struct GNUNET_DBUS_Client *client = GNUNET_new (struct GNUNET_DBUS_Client); | ||
25 | client->unique_name = GNUNET_strdup (unique_name); | ||
26 | client->data = NULL; | ||
27 | client->prefers_pretty_encodings = false; | ||
28 | client->ref_count = 1; | ||
29 | |||
30 | return client; | ||
31 | }; | ||
32 | |||
33 | void | ||
34 | GNUNET_DBUS_client_ref ( | ||
35 | struct GNUNET_DBUS_Client *client) | ||
36 | { | ||
37 | client->ref_count++; | ||
38 | } | ||
39 | |||
40 | void | ||
41 | GNUNET_DBUS_client_unref ( | ||
42 | struct GNUNET_DBUS_Client *client) | ||
43 | { | ||
44 | if (client->ref_count == 0) | ||
45 | { | ||
46 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unref client with ref count 0\n"); | ||
47 | LOG (GNUNET_ERROR_TYPE_ERROR, " unique_name == %s\n", client->unique_name); | ||
48 | GNUNET_abort_ (); | ||
49 | } | ||
50 | |||
51 | if (0 == --(client->ref_count)) | ||
52 | { | ||
53 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying client with unique name %s\n", client->unique_name); | ||
54 | |||
55 | GNUNET_free (client->unique_name); | ||
56 | GNUNET_free (client); | ||
57 | } | ||
58 | }; | ||
59 | |||
60 | const char * | ||
61 | GNUNET_DBUS_client_get_unique_name ( | ||
62 | const struct GNUNET_DBUS_Client *client) | ||
63 | { | ||
64 | return client->unique_name; | ||
65 | }; | ||
66 | |||
67 | void | ||
68 | GNUNET_DBUS_client_set_data ( | ||
69 | struct GNUNET_DBUS_Client *client, | ||
70 | void *data) | ||
71 | { | ||
72 | client->data = data; | ||
73 | }; | ||
74 | |||
75 | void * | ||
76 | GNUNET_DBUS_client_get_data ( | ||
77 | const struct GNUNET_DBUS_Client *client) | ||
78 | { | ||
79 | return client->data; | ||
80 | }; | ||
81 | |||
82 | void | ||
83 | GNUNET_DBUS_client_set_prefers_pretty_encodings ( | ||
84 | struct GNUNET_DBUS_Client *client, | ||
85 | bool prefers_pretty_encodings) | ||
86 | { | ||
87 | client->prefers_pretty_encodings = prefers_pretty_encodings; | ||
88 | } | ||
89 | |||
90 | bool | ||
91 | GNUNET_DBUS_client_get_prefers_pretty_encodings ( | ||
92 | const struct GNUNET_DBUS_Client *client) | ||
93 | { | ||
94 | return client->prefers_pretty_encodings; | ||
95 | }; | ||
96 | |||
97 | DBusMessage * | ||
98 | GNUNET_DBUS_client_create_method_call ( | ||
99 | struct GNUNET_DBUS_Client *client, | ||
100 | const char *object_path, | ||
101 | const char *interface, | ||
102 | const char *method, | ||
103 | bool pretty, | ||
104 | void (*return_callback)(DBusMessage *message)) | ||
105 | { | ||
106 | DBusMessage *ret = dbus_message_new_method_call ( | ||
107 | client->unique_name, | ||
108 | object_path, | ||
109 | interface, | ||
110 | method); | ||
111 | GNUNET_DBUS_message_set_pretty (ret, pretty); | ||
112 | if (return_callback) | ||
113 | { | ||
114 | LOG (GNUNET_ERROR_TYPE_ERROR, "Method calls on external objects not implemented yet.\n"); | ||
115 | GNUNET_abort_ (); | ||
116 | }; | ||
117 | return ret; | ||
118 | } | ||
119 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_interface.c b/src/lib/common/gnunet_dbus_lib_interface.c new file mode 100644 index 0000000..bbc3467 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_interface.c | |||
@@ -0,0 +1,275 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <dbus/dbus.h> | ||
4 | |||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_container_lib.h> | ||
8 | |||
9 | #include "gnunet_dbus_lib.h" | ||
10 | |||
11 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-interface", __VA_ARGS__) | ||
12 | |||
13 | struct GNUNET_DBUS_Interface | ||
14 | { | ||
15 | struct GNUNET_DBUS_MethodIterator *methods_front; | ||
16 | struct GNUNET_DBUS_MethodIterator *methods_back; | ||
17 | |||
18 | struct GNUNET_DBUS_SignalIterator *signals_front; | ||
19 | struct GNUNET_DBUS_SignalIterator *signals_back; | ||
20 | |||
21 | char *name; | ||
22 | unsigned ref_count; | ||
23 | }; | ||
24 | |||
25 | struct GNUNET_DBUS_Interface * | ||
26 | GNUNET_DBUS_interface_create ( | ||
27 | const char *name) | ||
28 | { | ||
29 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating interface %s\n", name); | ||
30 | |||
31 | struct GNUNET_DBUS_Interface *interface = GNUNET_new (struct GNUNET_DBUS_Interface); | ||
32 | |||
33 | interface->methods_front = NULL; | ||
34 | interface->methods_back = NULL; | ||
35 | interface->name = GNUNET_strdup (name); | ||
36 | interface->ref_count = 1; | ||
37 | |||
38 | return interface; | ||
39 | }; | ||
40 | |||
41 | void | ||
42 | GNUNET_DBUS_interface_ref ( | ||
43 | struct GNUNET_DBUS_Interface *interface) | ||
44 | { | ||
45 | interface->ref_count++; | ||
46 | }; | ||
47 | |||
48 | void | ||
49 | GNUNET_DBUS_interface_unref ( | ||
50 | struct GNUNET_DBUS_Interface *interface) | ||
51 | { | ||
52 | if (interface->ref_count == 0) | ||
53 | { | ||
54 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference interface with ref count 0\n"); | ||
55 | GNUNET_abort_ (); | ||
56 | }; | ||
57 | if (0 == --(interface->ref_count)) | ||
58 | { | ||
59 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying interface %s\n", interface->name); | ||
60 | |||
61 | struct GNUNET_DBUS_MethodIterator *methods_iter = interface->methods_front; | ||
62 | while (methods_iter) | ||
63 | { | ||
64 | struct GNUNET_DBUS_MethodIterator *next = methods_iter->next; | ||
65 | GNUNET_DBUS_method_unref (methods_iter->method); | ||
66 | GNUNET_free (methods_iter); | ||
67 | methods_iter = next; | ||
68 | }; | ||
69 | |||
70 | GNUNET_free (interface->name); | ||
71 | GNUNET_free (interface); | ||
72 | } | ||
73 | }; | ||
74 | |||
75 | void | ||
76 | GNUNET_DBUS_interface_add_method ( | ||
77 | struct GNUNET_DBUS_Interface *interface, | ||
78 | struct GNUNET_DBUS_Method *method) | ||
79 | { | ||
80 | struct GNUNET_DBUS_MethodIterator *meth_it = GNUNET_new (struct GNUNET_DBUS_MethodIterator); | ||
81 | meth_it->method = method; | ||
82 | GNUNET_DBUS_method_ref (method); | ||
83 | |||
84 | GNUNET_CONTAINER_DLL_insert (interface->methods_front, | ||
85 | interface->methods_back, | ||
86 | meth_it); | ||
87 | }; | ||
88 | |||
89 | void | ||
90 | GNUNET_DBUS_interface_add_signal ( | ||
91 | struct GNUNET_DBUS_Interface *interface, | ||
92 | struct GNUNET_DBUS_Signal *signal) | ||
93 | { | ||
94 | struct GNUNET_DBUS_SignalIterator *sig_it = GNUNET_new (struct GNUNET_DBUS_SignalIterator); | ||
95 | sig_it->signal = signal; | ||
96 | GNUNET_DBUS_signal_ref (signal); | ||
97 | |||
98 | GNUNET_CONTAINER_DLL_insert (interface->signals_front, | ||
99 | interface->signals_back, | ||
100 | sig_it); | ||
101 | }; | ||
102 | |||
103 | const char * | ||
104 | GNUNET_DBUS_interface_get_name ( | ||
105 | const struct GNUNET_DBUS_Interface *interface) | ||
106 | { | ||
107 | return interface->name; | ||
108 | }; | ||
109 | |||
110 | const struct GNUNET_DBUS_MethodIterator * | ||
111 | GNUNET_DBUS_interface_iterate_methods ( | ||
112 | const struct GNUNET_DBUS_Interface *interface) | ||
113 | { | ||
114 | return interface->methods_front; | ||
115 | }; | ||
116 | |||
117 | const struct GNUNET_DBUS_SignalIterator * | ||
118 | GNUNET_DBUS_interface_iterate_signals ( | ||
119 | const struct GNUNET_DBUS_Interface *interface) | ||
120 | { | ||
121 | return interface->signals_front; | ||
122 | } | ||
123 | |||
124 | static void | ||
125 | introspectable_introspect ( | ||
126 | struct GNUNET_DBUS_MethodContext *mc) | ||
127 | { | ||
128 | char *data = NULL; | ||
129 | char *new_data = NULL; | ||
130 | |||
131 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Introspecting\n"); | ||
132 | struct GNUNET_DBUS_Object *object = mc->object; | ||
133 | |||
134 | GNUNET_asprintf (&data, "%s", DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE); | ||
135 | GNUNET_asprintf (&new_data, "%s<node>\n", data); | ||
136 | GNUNET_free (data); data = new_data; | ||
137 | |||
138 | const struct GNUNET_DBUS_InterfaceIterator *int_it = GNUNET_DBUS_object_iterate_interfaces (object); | ||
139 | while (int_it) | ||
140 | { | ||
141 | struct GNUNET_DBUS_Interface *interface = int_it->interface; | ||
142 | const char *interface_name = GNUNET_DBUS_interface_get_name (interface); | ||
143 | GNUNET_asprintf (&new_data, "%s <interface name='%s'>\n", data, interface_name); | ||
144 | GNUNET_free (data); data = new_data; | ||
145 | const struct GNUNET_DBUS_MethodIterator *meth_it = GNUNET_DBUS_interface_iterate_methods (interface); | ||
146 | while (meth_it) | ||
147 | { | ||
148 | struct GNUNET_DBUS_Method *method = meth_it->method; | ||
149 | const char *method_name = GNUNET_DBUS_method_get_name (method); | ||
150 | GNUNET_asprintf (&new_data, "%s <method name='%s'>\n", data, method_name); | ||
151 | GNUNET_free (data); data = new_data; | ||
152 | const struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_DBUS_method_iterate_args (method); | ||
153 | while (arg_it) | ||
154 | { | ||
155 | struct GNUNET_DBUS_Arg *arg = arg_it->arg; | ||
156 | const char *arg_name = GNUNET_DBUS_arg_get_name (arg); | ||
157 | const char *signature = GNUNET_DBUS_arg_get_signature (arg); | ||
158 | GNUNET_asprintf ( | ||
159 | &new_data, | ||
160 | "%s <arg name='%s' type='%s' direction='in'/>\n", | ||
161 | data, | ||
162 | arg_name, | ||
163 | signature); | ||
164 | GNUNET_free (data); data = new_data; | ||
165 | arg_it = arg_it->next; | ||
166 | }; | ||
167 | |||
168 | arg_it = GNUNET_DBUS_method_iterate_return_args (method); | ||
169 | while (arg_it) | ||
170 | { | ||
171 | struct GNUNET_DBUS_Arg *arg = arg_it->arg; | ||
172 | const char *arg_name = GNUNET_DBUS_arg_get_name (arg); | ||
173 | const char *signature = GNUNET_DBUS_arg_get_signature (arg); | ||
174 | GNUNET_asprintf ( | ||
175 | &new_data, | ||
176 | "%s <arg name='%s' type='%s' direction='out'/>\n", | ||
177 | data, | ||
178 | arg_name, | ||
179 | signature); | ||
180 | GNUNET_free (data); data = new_data; | ||
181 | arg_it = arg_it->next; | ||
182 | }; | ||
183 | GNUNET_asprintf (&new_data, "%s </method>\n", data); | ||
184 | GNUNET_free (data); data = new_data; | ||
185 | meth_it = meth_it->next; | ||
186 | }; | ||
187 | const struct GNUNET_DBUS_SignalIterator *sig_it = GNUNET_DBUS_interface_iterate_signals (interface); | ||
188 | while (sig_it) | ||
189 | { | ||
190 | struct GNUNET_DBUS_Signal *signal = sig_it->signal; | ||
191 | const char *signal_name = GNUNET_DBUS_signal_get_name (signal); | ||
192 | GNUNET_asprintf (&new_data, "%s <signal name='%s'>\n", data, signal_name); | ||
193 | GNUNET_free (data); data = new_data; | ||
194 | const struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_DBUS_signal_iterate_args (signal); | ||
195 | while (arg_it) | ||
196 | { | ||
197 | struct GNUNET_DBUS_Arg *arg = arg_it->arg; | ||
198 | const char *arg_name = GNUNET_DBUS_arg_get_name (arg); | ||
199 | const char *signature = GNUNET_DBUS_arg_get_signature (arg); | ||
200 | GNUNET_asprintf ( | ||
201 | &new_data, | ||
202 | "%s <arg name='%s' type='%s'/>\n", | ||
203 | data, | ||
204 | arg_name, | ||
205 | signature); | ||
206 | GNUNET_free (data); data = new_data; | ||
207 | arg_it = arg_it->next; | ||
208 | } | ||
209 | GNUNET_asprintf (&new_data, "%s </signal>\n", data); | ||
210 | GNUNET_free (data); data = new_data; | ||
211 | sig_it = sig_it->next; | ||
212 | }; | ||
213 | GNUNET_asprintf (&new_data, "%s </interface>\n", data); | ||
214 | GNUNET_free (data); data = new_data; | ||
215 | int_it = int_it->next; | ||
216 | }; | ||
217 | const struct GNUNET_DBUS_ObjectIterator *obj_it = GNUNET_DBUS_object_iterate_subobjects (object); | ||
218 | while (obj_it) | ||
219 | { | ||
220 | const char *obj_name = GNUNET_DBUS_object_get_name (obj_it->object); | ||
221 | GNUNET_asprintf (&new_data, "%s <node name='%s'/>\n", data, obj_name); | ||
222 | GNUNET_free (data); data = new_data; | ||
223 | obj_it = obj_it->next; | ||
224 | } | ||
225 | GNUNET_asprintf (&new_data, "%s</node>\n", data); | ||
226 | GNUNET_free (data); data = new_data; | ||
227 | |||
228 | DBusMessage *reply = GNUNET_DBUS_method_context_create_reply (mc); | ||
229 | DBusMessageIter reply_iter; | ||
230 | dbus_message_iter_init_append (reply, &reply_iter); | ||
231 | GNUNET_DBUS_push_string (reply, &reply_iter, (const char *const *)&data); | ||
232 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
233 | GNUNET_free (data); | ||
234 | }; | ||
235 | |||
236 | struct GNUNET_DBUS_Interface *interface_introspectable; | ||
237 | |||
238 | static void construct_interface_introspectable () | ||
239 | __attribute__((constructor)); | ||
240 | |||
241 | static void destruct_interface_introspectable () | ||
242 | __attribute__((destructor)); | ||
243 | |||
244 | static void construct_interface_introspectable () | ||
245 | { | ||
246 | interface_introspectable = GNUNET_DBUS_interface_create ("org.freedesktop.DBus.Introspectable"); | ||
247 | struct GNUNET_DBUS_Method *introspect = GNUNET_DBUS_method_create ("Introspect", introspectable_introspect); | ||
248 | GNUNET_DBUS_method_add_return_arg (introspect, "data", GNUNET_DBUS_SIGNATURE_STRING); | ||
249 | GNUNET_DBUS_interface_add_method (interface_introspectable, introspect); | ||
250 | } | ||
251 | |||
252 | static void destruct_interface_introspectable () | ||
253 | { | ||
254 | GNUNET_DBUS_interface_unref (interface_introspectable); | ||
255 | } | ||
256 | |||
257 | struct GNUNET_DBUS_Interface * | ||
258 | GNUNET_DBUS_interface_introspectable () | ||
259 | { | ||
260 | return interface_introspectable; | ||
261 | }; | ||
262 | |||
263 | const struct GNUNET_DBUS_InterfaceIterator * | ||
264 | GNUNET_DBUS_interface_find ( | ||
265 | const struct GNUNET_DBUS_InterfaceIterator *int_it, | ||
266 | const char *name) | ||
267 | { | ||
268 | for (; int_it; int_it = int_it->next) | ||
269 | { | ||
270 | if (! strcmp (name, int_it->interface->name)) | ||
271 | return int_it; | ||
272 | } | ||
273 | return NULL; | ||
274 | } | ||
275 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_message.c b/src/lib/common/gnunet_dbus_lib_message.c new file mode 100644 index 0000000..1d76f84 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_message.c | |||
@@ -0,0 +1,62 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | |||
6 | #include "gnunet_dbus_lib_message.h" | ||
7 | |||
8 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-message", __VA_ARGS__) | ||
9 | |||
10 | static dbus_int32_t | ||
11 | pretty_slot_id () | ||
12 | { | ||
13 | static dbus_int32_t id = -1; | ||
14 | if (-1 == id) | ||
15 | { | ||
16 | dbus_bool_t succ = dbus_message_allocate_data_slot (&id); | ||
17 | if (! succ || -1 == id) | ||
18 | { | ||
19 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_message_allocate_data_slot failed. id == %lld\n", (long long)id); | ||
20 | GNUNET_abort_ (); | ||
21 | }; | ||
22 | }; | ||
23 | |||
24 | return id; | ||
25 | }; | ||
26 | |||
27 | bool | ||
28 | GNUNET_DBUS_message_get_pretty ( | ||
29 | DBusMessage *message) | ||
30 | { | ||
31 | return (bool)dbus_message_get_data (message, pretty_slot_id ()); | ||
32 | } | ||
33 | |||
34 | void | ||
35 | GNUNET_DBUS_message_set_pretty ( | ||
36 | DBusMessage *message, | ||
37 | bool pretty) | ||
38 | { | ||
39 | dbus_int32_t id = pretty_slot_id (); | ||
40 | bool succ = dbus_message_set_data (message, id, (void *)pretty, NULL); | ||
41 | if (! succ) | ||
42 | { | ||
43 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_message_set_data failed. id == %lld\n", (long long)id); | ||
44 | GNUNET_abort_ (); | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | void | ||
49 | GNUNET_DBUS_message_set_destination ( | ||
50 | DBusMessage *message, | ||
51 | struct GNUNET_DBUS_Client *client) | ||
52 | { | ||
53 | dbus_message_set_destination (message, GNUNET_DBUS_client_get_unique_name (client)); | ||
54 | } | ||
55 | |||
56 | void | ||
57 | GNUNET_DBUS_message_unset_destination ( | ||
58 | DBusMessage *message) | ||
59 | { | ||
60 | dbus_message_set_destination (message, NULL); | ||
61 | } | ||
62 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_method.c b/src/lib/common/gnunet_dbus_lib_method.c new file mode 100644 index 0000000..ebf631d --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_method.c | |||
@@ -0,0 +1,149 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_container_lib.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib.h" | ||
8 | |||
9 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-method", __VA_ARGS__) | ||
10 | |||
11 | struct GNUNET_DBUS_Method | ||
12 | { | ||
13 | struct GNUNET_DBUS_ArgIterator *args_front; | ||
14 | struct GNUNET_DBUS_ArgIterator *args_back; | ||
15 | |||
16 | struct GNUNET_DBUS_ArgIterator *return_args_front; | ||
17 | struct GNUNET_DBUS_ArgIterator *return_args_back; | ||
18 | |||
19 | char *name; | ||
20 | |||
21 | void (*underlying_method)(struct GNUNET_DBUS_MethodContext *mc); | ||
22 | |||
23 | unsigned ref_count; | ||
24 | }; | ||
25 | |||
26 | struct GNUNET_DBUS_Method * | ||
27 | GNUNET_DBUS_method_create ( | ||
28 | const char *name, | ||
29 | void (*underlying_method)(struct GNUNET_DBUS_MethodContext *mc)) | ||
30 | { | ||
31 | struct GNUNET_DBUS_Method *method = GNUNET_new (struct GNUNET_DBUS_Method); | ||
32 | method->name = GNUNET_strdup (name); | ||
33 | method->underlying_method = underlying_method; | ||
34 | method->ref_count = 1; | ||
35 | |||
36 | return method; | ||
37 | }; | ||
38 | |||
39 | void | ||
40 | GNUNET_DBUS_method_ref ( | ||
41 | struct GNUNET_DBUS_Method *method) | ||
42 | { | ||
43 | method->ref_count++; | ||
44 | }; | ||
45 | |||
46 | void | ||
47 | GNUNET_DBUS_method_unref ( | ||
48 | struct GNUNET_DBUS_Method *method) | ||
49 | { | ||
50 | if (method->ref_count == 0) | ||
51 | { | ||
52 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference method with ref count 0\n"); | ||
53 | GNUNET_abort_ (); | ||
54 | }; | ||
55 | if (0 == --(method->ref_count)) | ||
56 | { | ||
57 | struct GNUNET_DBUS_ArgIterator *arg_it = method->args_front; | ||
58 | while (arg_it) | ||
59 | { | ||
60 | struct GNUNET_DBUS_ArgIterator *next = arg_it->next; | ||
61 | GNUNET_DBUS_arg_unref (arg_it->arg); | ||
62 | GNUNET_free (arg_it); | ||
63 | arg_it = next; | ||
64 | } | ||
65 | |||
66 | arg_it = method->return_args_front; | ||
67 | while (arg_it) | ||
68 | { | ||
69 | struct GNUNET_DBUS_ArgIterator *next = arg_it->next; | ||
70 | GNUNET_DBUS_arg_unref (arg_it->arg); | ||
71 | GNUNET_free (arg_it); | ||
72 | arg_it = next; | ||
73 | } | ||
74 | |||
75 | GNUNET_free (method->name); | ||
76 | GNUNET_free (method); | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | void | ||
81 | GNUNET_DBUS_method_add_arg ( | ||
82 | struct GNUNET_DBUS_Method *method, | ||
83 | const char *name, | ||
84 | const char *signature) | ||
85 | { | ||
86 | struct GNUNET_DBUS_Arg *arg = GNUNET_DBUS_arg_create (name, signature); | ||
87 | struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_new (struct GNUNET_DBUS_ArgIterator); | ||
88 | arg_it->arg = arg; | ||
89 | GNUNET_CONTAINER_DLL_insert_tail (method->args_front, | ||
90 | method->args_back, | ||
91 | arg_it); | ||
92 | }; | ||
93 | |||
94 | void | ||
95 | GNUNET_DBUS_method_add_return_arg ( | ||
96 | struct GNUNET_DBUS_Method *method, | ||
97 | const char *name, | ||
98 | const char *signature) | ||
99 | { | ||
100 | struct GNUNET_DBUS_Arg *arg = GNUNET_DBUS_arg_create (name, signature); | ||
101 | struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_new (struct GNUNET_DBUS_ArgIterator); | ||
102 | arg_it->arg = arg; | ||
103 | GNUNET_CONTAINER_DLL_insert_tail (method->return_args_front, | ||
104 | method->return_args_back, | ||
105 | arg_it); | ||
106 | }; | ||
107 | |||
108 | const char * | ||
109 | GNUNET_DBUS_method_get_name ( | ||
110 | const struct GNUNET_DBUS_Method *method) | ||
111 | { | ||
112 | return method->name; | ||
113 | }; | ||
114 | |||
115 | const struct GNUNET_DBUS_ArgIterator * | ||
116 | GNUNET_DBUS_method_iterate_args ( | ||
117 | const struct GNUNET_DBUS_Method *method) | ||
118 | { | ||
119 | return method->args_front; | ||
120 | }; | ||
121 | |||
122 | const struct GNUNET_DBUS_ArgIterator * | ||
123 | GNUNET_DBUS_method_iterate_return_args ( | ||
124 | const struct GNUNET_DBUS_Method *method) | ||
125 | { | ||
126 | return method->return_args_front; | ||
127 | }; | ||
128 | |||
129 | void | ||
130 | GNUNET_DBUS_method_call ( | ||
131 | struct GNUNET_DBUS_Method *method, | ||
132 | struct GNUNET_DBUS_MethodContext *mc) | ||
133 | { | ||
134 | method->underlying_method (mc); | ||
135 | }; | ||
136 | |||
137 | const struct GNUNET_DBUS_MethodIterator * | ||
138 | GNUNET_DBUS_method_find ( | ||
139 | const struct GNUNET_DBUS_MethodIterator *meth_it, | ||
140 | const char *name) | ||
141 | { | ||
142 | for (; meth_it; meth_it = meth_it->next) | ||
143 | { | ||
144 | if (! strcmp (name, meth_it->method->name)) | ||
145 | return meth_it; | ||
146 | } | ||
147 | return NULL; | ||
148 | } | ||
149 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_method_context.c b/src/lib/common/gnunet_dbus_lib_method_context.c new file mode 100644 index 0000000..f7a4bac --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_method_context.c | |||
@@ -0,0 +1,83 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <dbus/dbus.h> | ||
4 | |||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_container_lib.h> | ||
8 | |||
9 | #include "gnunet_dbus_lib.h" | ||
10 | |||
11 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-method-context", __VA_ARGS__) | ||
12 | |||
13 | struct GNUNET_DBUS_MethodContext * | ||
14 | GNUNET_DBUS_method_context_create ( | ||
15 | struct GNUNET_DBUS_Client *client, | ||
16 | struct GNUNET_DBUS_Service *service, | ||
17 | struct GNUNET_DBUS_Object *object, | ||
18 | struct GNUNET_DBUS_Interface *interface, | ||
19 | struct GNUNET_DBUS_Method *method, | ||
20 | DBusMessage *message) | ||
21 | { | ||
22 | struct GNUNET_DBUS_MethodContext *ret = GNUNET_new (struct GNUNET_DBUS_MethodContext); | ||
23 | ret->client = client; | ||
24 | ret->service = service; | ||
25 | ret->object = object; | ||
26 | ret->interface = interface; | ||
27 | ret->method = method; | ||
28 | ret->message = message; | ||
29 | ret->expects_reply = ! dbus_message_get_no_reply (message); | ||
30 | |||
31 | ret->replied = false; | ||
32 | ret->ref_count = 1; | ||
33 | dbus_message_ref (message); | ||
34 | |||
35 | return ret; | ||
36 | }; | ||
37 | |||
38 | void | ||
39 | GNUNET_DBUS_method_context_ref ( | ||
40 | struct GNUNET_DBUS_MethodContext *mc) | ||
41 | { | ||
42 | mc->ref_count++; | ||
43 | }; | ||
44 | |||
45 | void | ||
46 | GNUNET_DBUS_method_context_unref ( | ||
47 | struct GNUNET_DBUS_MethodContext *mc) | ||
48 | { | ||
49 | if (0 == mc->ref_count) | ||
50 | { | ||
51 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference method context with ref count 0\n"); | ||
52 | GNUNET_abort_ (); | ||
53 | }; | ||
54 | if (0 == --(mc->ref_count)) | ||
55 | { | ||
56 | dbus_message_unref (mc->message); | ||
57 | GNUNET_free (mc); | ||
58 | } | ||
59 | }; | ||
60 | |||
61 | void | ||
62 | GNUNET_DBUS_method_context_send_reply ( | ||
63 | struct GNUNET_DBUS_MethodContext *mc, | ||
64 | DBusMessage *reply) | ||
65 | { | ||
66 | if (! mc->expects_reply) | ||
67 | return; | ||
68 | |||
69 | GNUNET_DBUS_service_send (mc->service, reply); | ||
70 | dbus_message_unref (reply); | ||
71 | }; | ||
72 | |||
73 | DBusMessage * | ||
74 | GNUNET_DBUS_method_context_create_reply ( | ||
75 | struct GNUNET_DBUS_MethodContext *mc) | ||
76 | { | ||
77 | DBusMessage *ret = dbus_message_new_method_return (mc->message); | ||
78 | //GNUNET_DBUS_message_set_pretty (ret, GNUNET_DBUS_client_get_prefers_pretty_encodings (mc->client)); | ||
79 | GNUNET_DBUS_message_set_pretty (ret, GNUNET_DBUS_message_get_pretty (mc->message)); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_object.c b/src/lib/common/gnunet_dbus_lib_object.c new file mode 100644 index 0000000..816f587 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_object.c | |||
@@ -0,0 +1,192 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <inttypes.h> | ||
4 | |||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_container_lib.h> | ||
8 | |||
9 | #include "gnunet_dbus_lib.h" | ||
10 | |||
11 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-object", __VA_ARGS__) | ||
12 | |||
13 | struct GNUNET_DBUS_Object | ||
14 | { | ||
15 | struct GNUNET_DBUS_InterfaceIterator *interfaces_front; | ||
16 | struct GNUNET_DBUS_InterfaceIterator *interfaces_back; | ||
17 | |||
18 | struct GNUNET_DBUS_ObjectIterator *subobjects_front; | ||
19 | struct GNUNET_DBUS_ObjectIterator *subobjects_back; | ||
20 | |||
21 | char *name; | ||
22 | void *data; | ||
23 | unsigned ref_count; | ||
24 | }; | ||
25 | |||
26 | struct GNUNET_DBUS_Object * | ||
27 | GNUNET_DBUS_object_create ( | ||
28 | const char *name, | ||
29 | void *data) | ||
30 | { | ||
31 | struct GNUNET_DBUS_Object *object = GNUNET_new (struct GNUNET_DBUS_Object); | ||
32 | object->name = GNUNET_strdup (name); | ||
33 | object->data = data; | ||
34 | object->interfaces_front = NULL; | ||
35 | object->interfaces_back = NULL; | ||
36 | object->subobjects_front = NULL; | ||
37 | object->subobjects_back = NULL; | ||
38 | object->ref_count = 1; | ||
39 | |||
40 | return object; | ||
41 | }; | ||
42 | |||
43 | void | ||
44 | GNUNET_DBUS_object_ref ( | ||
45 | struct GNUNET_DBUS_Object *object) | ||
46 | { | ||
47 | object->ref_count++; | ||
48 | }; | ||
49 | |||
50 | void | ||
51 | GNUNET_DBUS_object_unref ( | ||
52 | struct GNUNET_DBUS_Object *object) | ||
53 | { | ||
54 | if (object->ref_count == 0) | ||
55 | { | ||
56 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference object with ref count 0\n"); | ||
57 | GNUNET_abort_ (); | ||
58 | }; | ||
59 | if (0 == --(object->ref_count)) | ||
60 | { | ||
61 | struct GNUNET_DBUS_InterfaceIterator *int_it = object->interfaces_front; | ||
62 | while (int_it) | ||
63 | { | ||
64 | struct GNUNET_DBUS_InterfaceIterator *next = int_it->next; | ||
65 | GNUNET_DBUS_interface_unref (int_it->interface); | ||
66 | GNUNET_free (int_it); | ||
67 | int_it = next; | ||
68 | }; | ||
69 | |||
70 | struct GNUNET_DBUS_ObjectIterator *obj_it = object->subobjects_front; | ||
71 | while (obj_it) | ||
72 | { | ||
73 | struct GNUNET_DBUS_ObjectIterator *next = obj_it->next; | ||
74 | GNUNET_DBUS_object_unref (obj_it->object); | ||
75 | GNUNET_free (obj_it); | ||
76 | obj_it = next; | ||
77 | }; | ||
78 | |||
79 | GNUNET_free (object->name); | ||
80 | GNUNET_free (object); | ||
81 | } | ||
82 | }; | ||
83 | |||
84 | const char * | ||
85 | GNUNET_DBUS_object_get_name ( | ||
86 | const struct GNUNET_DBUS_Object *object) | ||
87 | { | ||
88 | return object->name; | ||
89 | }; | ||
90 | |||
91 | void | ||
92 | GNUNET_DBUS_object_add_interface ( | ||
93 | struct GNUNET_DBUS_Object *object, | ||
94 | struct GNUNET_DBUS_Interface *interface) | ||
95 | { | ||
96 | struct GNUNET_DBUS_InterfaceIterator *int_it = GNUNET_new (struct GNUNET_DBUS_InterfaceIterator); | ||
97 | int_it->interface = interface; | ||
98 | GNUNET_DBUS_interface_ref (interface); | ||
99 | |||
100 | GNUNET_CONTAINER_DLL_insert (object->interfaces_front, | ||
101 | object->interfaces_back, | ||
102 | int_it); | ||
103 | }; | ||
104 | |||
105 | const struct GNUNET_DBUS_InterfaceIterator * | ||
106 | GNUNET_DBUS_object_iterate_interfaces ( | ||
107 | struct GNUNET_DBUS_Object *object) | ||
108 | { | ||
109 | return object->interfaces_front; | ||
110 | }; | ||
111 | |||
112 | void * | ||
113 | GNUNET_DBUS_object_get_data ( | ||
114 | struct GNUNET_DBUS_Object *object) | ||
115 | { | ||
116 | return object->data; | ||
117 | }; | ||
118 | |||
119 | struct GNUNET_DBUS_Object * | ||
120 | GNUNET_DBUS_object_create_uniquely_named_subobject ( | ||
121 | struct GNUNET_DBUS_Object *object, | ||
122 | void *data) | ||
123 | { | ||
124 | while(true) | ||
125 | { | ||
126 | char name[9]; | ||
127 | uint32_t id = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 0xffffffff); | ||
128 | GNUNET_snprintf (name, sizeof(name), "%08" PRIx32, id); | ||
129 | const struct GNUNET_DBUS_ObjectIterator *obj_it = GNUNET_DBUS_object_iterate_subobjects (object); | ||
130 | while (true) | ||
131 | { | ||
132 | if (! obj_it) | ||
133 | { | ||
134 | struct GNUNET_DBUS_Object *subobject = GNUNET_DBUS_object_create (name, data); | ||
135 | GNUNET_DBUS_object_add_subobject (object, subobject); | ||
136 | return subobject; | ||
137 | } | ||
138 | |||
139 | const struct GNUNET_DBUS_Object *test_object = obj_it->object; | ||
140 | if (0 == strcmp (name, GNUNET_DBUS_object_get_name (test_object))) | ||
141 | break; | ||
142 | |||
143 | obj_it = obj_it->next; | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | void | ||
149 | GNUNET_DBUS_object_add_subobject ( | ||
150 | struct GNUNET_DBUS_Object *object, | ||
151 | struct GNUNET_DBUS_Object *subobject) | ||
152 | { | ||
153 | struct GNUNET_DBUS_ObjectIterator *obj_it = GNUNET_new (struct GNUNET_DBUS_ObjectIterator); | ||
154 | obj_it->object = subobject; | ||
155 | GNUNET_DBUS_object_ref (subobject); | ||
156 | |||
157 | GNUNET_CONTAINER_DLL_insert (object->subobjects_front, | ||
158 | object->subobjects_back, | ||
159 | obj_it); | ||
160 | }; | ||
161 | |||
162 | void | ||
163 | GNUNET_DBUS_object_remove_subobject ( | ||
164 | struct GNUNET_DBUS_Object *object, | ||
165 | struct GNUNET_DBUS_ObjectIterator *subobject_it) | ||
166 | { | ||
167 | GNUNET_DBUS_object_unref (subobject_it->object); | ||
168 | GNUNET_CONTAINER_DLL_remove (object->subobjects_front, | ||
169 | object->subobjects_back, | ||
170 | subobject_it); | ||
171 | GNUNET_free (subobject_it); | ||
172 | }; | ||
173 | |||
174 | struct GNUNET_DBUS_ObjectIterator * | ||
175 | GNUNET_DBUS_object_iterate_subobjects ( | ||
176 | const struct GNUNET_DBUS_Object *object) | ||
177 | { | ||
178 | return object->subobjects_front; | ||
179 | } | ||
180 | |||
181 | const struct GNUNET_DBUS_ObjectIterator * | ||
182 | GNUNET_DBUS_object_find ( | ||
183 | const struct GNUNET_DBUS_ObjectIterator *object_it, | ||
184 | const char *name) | ||
185 | { | ||
186 | while (object_it && strcmp (name, object_it->object->name)) | ||
187 | object_it = object_it->next; | ||
188 | |||
189 | return object_it; | ||
190 | } | ||
191 | |||
192 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_object_path.c b/src/lib/common/gnunet_dbus_lib_object_path.c new file mode 100644 index 0000000..72a155f --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_object_path.c | |||
@@ -0,0 +1,162 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_container_lib.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib.h" | ||
8 | |||
9 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-object-path", __VA_ARGS__) | ||
10 | |||
11 | struct GNUNET_DBUS_ObjectPath | ||
12 | { | ||
13 | size_t objects_len; | ||
14 | struct GNUNET_DBUS_Object **objects; | ||
15 | size_t ref_count; | ||
16 | }; | ||
17 | |||
18 | struct GNUNET_DBUS_ObjectPath * | ||
19 | GNUNET_DBUS_object_path_create ( | ||
20 | struct GNUNET_DBUS_Service *service, | ||
21 | ...) | ||
22 | { | ||
23 | struct GNUNET_DBUS_ObjectPath *path = GNUNET_new (struct GNUNET_DBUS_ObjectPath); | ||
24 | path->objects_len = 1; | ||
25 | path->ref_count = 1; | ||
26 | |||
27 | va_list vl; | ||
28 | va_start (vl, service); | ||
29 | while (va_arg (vl, struct GNUNET_DBUS_Object *)) | ||
30 | { | ||
31 | path->objects_len++; | ||
32 | } | ||
33 | va_end (vl); | ||
34 | |||
35 | path->objects = GNUNET_malloc (sizeof (struct GNUNET_DBUS_Object *) * (path->objects_len + 1)); | ||
36 | va_start (vl, service); | ||
37 | size_t i; | ||
38 | struct GNUNET_DBUS_Object *elem = GNUNET_DBUS_service_get_root_object (service); | ||
39 | path->objects[0] = elem; | ||
40 | GNUNET_DBUS_object_ref (elem); | ||
41 | for (i = 1; i < path->objects_len; i++) | ||
42 | { | ||
43 | elem = va_arg (vl, struct GNUNET_DBUS_Object *); | ||
44 | path->objects[i] = elem; | ||
45 | GNUNET_DBUS_object_ref (elem); | ||
46 | } | ||
47 | path->objects[path->objects_len] = NULL; | ||
48 | va_end (vl); | ||
49 | |||
50 | return path; | ||
51 | } | ||
52 | |||
53 | void | ||
54 | GNUNET_DBUS_object_path_unref ( | ||
55 | struct GNUNET_DBUS_ObjectPath *path) | ||
56 | { | ||
57 | if (path->ref_count == 0) | ||
58 | { | ||
59 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference object path with ref count 0\n"); | ||
60 | |||
61 | /* This will probably segfault, but oh well */ | ||
62 | char *path_as_str = GNUNET_DBUS_object_path_to_string (path); | ||
63 | LOG (GNUNET_ERROR_TYPE_ERROR, " path == %s\n", path_as_str); | ||
64 | GNUNET_abort_ (); | ||
65 | }; | ||
66 | if (0 == --(path->ref_count)) | ||
67 | { | ||
68 | size_t i; | ||
69 | for (i = 0; i < path->objects_len; i++) | ||
70 | { | ||
71 | GNUNET_DBUS_object_unref (path->objects[i]); | ||
72 | } | ||
73 | |||
74 | GNUNET_free (path->objects); | ||
75 | GNUNET_free (path); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | char * | ||
80 | GNUNET_DBUS_object_path_to_string ( | ||
81 | const struct GNUNET_DBUS_ObjectPath *path) | ||
82 | { | ||
83 | char *data; | ||
84 | char *new_data; | ||
85 | |||
86 | struct GNUNET_DBUS_Object **obj = path->objects; | ||
87 | |||
88 | obj++; | ||
89 | if (NULL == *obj) | ||
90 | { | ||
91 | GNUNET_asprintf (&data, "/"); | ||
92 | return data; | ||
93 | } | ||
94 | |||
95 | GNUNET_asprintf (&data, "%s", ""); | ||
96 | while (*obj) | ||
97 | { | ||
98 | GNUNET_asprintf (&new_data, "%s/%s", data, GNUNET_DBUS_object_get_name (*obj)); | ||
99 | GNUNET_free (data); data = new_data; | ||
100 | obj++; | ||
101 | } | ||
102 | |||
103 | return data; | ||
104 | } | ||
105 | |||
106 | #if 0 | ||
107 | struct GNUNET_DBUS_ObjectPath * | ||
108 | GNUNET_DBUS_object_path_create_from_string ( | ||
109 | const struct GNUNET_DBUS_Service *service, | ||
110 | const char *path_str) | ||
111 | { | ||
112 | char **path_decomposed = NULL; | ||
113 | dbus_bool_t succ = dbus_message_get_path_decomposed (dbus_message, &path_decomposed); | ||
114 | if (! succ) | ||
115 | { | ||
116 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_message_get_path_decomposed failed.\n"); | ||
117 | GNUNET_abort_ (); | ||
118 | }; | ||
119 | |||
120 | struct GNUNET_DBUS_ObjectPath *object_path = GNUNET_new (struct GNUNET_DBUS_ObjectPath); | ||
121 | object_path->objects_len = 0; | ||
122 | const char **path_element = path_decomposed; | ||
123 | while (*path_element) | ||
124 | { | ||
125 | object_path->objects_len++; | ||
126 | path_element++; | ||
127 | } | ||
128 | |||
129 | object_path->objects = GNUNET_malloc (sizeof (struct GNUNET_DBUS_Object *) * object_path->objects_len); | ||
130 | |||
131 | const struct GNUNET_DBUS_Object *object = GNUNET_DBUS_service_get_root_object (service); | ||
132 | struct GNUNET_DBUS_Object **pos = object_path->objects; | ||
133 | *pos++ = object; | ||
134 | path_element = path_decomposed; | ||
135 | while (*path_element) | ||
136 | { | ||
137 | const struct GNUNET_DBUS_ObjectIterator *start = GNUNET_DBUS_object_iterate_subobjects (object); | ||
138 | const struct GNUNET_DBUS_ObjectIterator *found = GNUNET_DBUS_object_find (start, *path_element); | ||
139 | if (! found) | ||
140 | { | ||
141 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Invalid object path \"%s\"\n", path_str); | ||
142 | return NULL; | ||
143 | }; | ||
144 | |||
145 | object = found->object; | ||
146 | *pos++ = object; | ||
147 | path_element++; | ||
148 | } | ||
149 | |||
150 | object_path->ref_count = 1; | ||
151 | |||
152 | return object_path; | ||
153 | } | ||
154 | #endif | ||
155 | |||
156 | struct GNUNET_DBUS_Object * | ||
157 | GNUNET_DBUS_object_path_get_destination ( | ||
158 | const struct GNUNET_DBUS_ObjectPath *path) | ||
159 | { | ||
160 | return path->objects[path->objects_len - 1]; | ||
161 | } | ||
162 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_pop.c b/src/lib/common/gnunet_dbus_lib_pop.c new file mode 100644 index 0000000..dd945e4 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_pop.c | |||
@@ -0,0 +1,733 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_strings_lib.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib.h" | ||
8 | #include "gnunet_crypto_dbus_lib.h" | ||
9 | |||
10 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-pop", __VA_ARGS__) | ||
11 | |||
12 | static DBusMessage * | ||
13 | pop_basic ( | ||
14 | DBusMessage *message, | ||
15 | DBusMessageIter *iter, | ||
16 | const char *arg_name, | ||
17 | int expected_type, | ||
18 | void *value) | ||
19 | { | ||
20 | int arg_type = dbus_message_iter_get_arg_type (iter); | ||
21 | if (expected_type != arg_type) | ||
22 | { | ||
23 | return dbus_message_new_error_printf ( | ||
24 | message, | ||
25 | DBUS_ERROR_INVALID_ARGS, | ||
26 | "Bad argument for '%s'. Expected %s. Got %s", | ||
27 | arg_name, | ||
28 | GNUNET_DBUS_signature_typecode_to_string (expected_type), | ||
29 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
30 | }; | ||
31 | dbus_message_iter_get_basic (iter, value); | ||
32 | dbus_message_iter_next (iter); | ||
33 | |||
34 | return NULL; | ||
35 | }; | ||
36 | |||
37 | DBusMessage * | ||
38 | GNUNET_DBUS_pop_byte ( | ||
39 | DBusMessage *message, | ||
40 | DBusMessageIter *iter, | ||
41 | const char *arg_name, | ||
42 | unsigned char *value) | ||
43 | { | ||
44 | return pop_basic ( | ||
45 | message, | ||
46 | iter, | ||
47 | arg_name, | ||
48 | DBUS_TYPE_BYTE, | ||
49 | (void *)value); | ||
50 | }; | ||
51 | |||
52 | DBusMessage * | ||
53 | GNUNET_DBUS_pop_boolean ( | ||
54 | DBusMessage *message, | ||
55 | DBusMessageIter *iter, | ||
56 | const char *arg_name, | ||
57 | dbus_bool_t *value) | ||
58 | { | ||
59 | return pop_basic ( | ||
60 | message, | ||
61 | iter, | ||
62 | arg_name, | ||
63 | DBUS_TYPE_BOOLEAN, | ||
64 | (void *)value); | ||
65 | }; | ||
66 | |||
67 | DBusMessage * | ||
68 | GNUNET_DBUS_pop_int16 ( | ||
69 | DBusMessage *message, | ||
70 | DBusMessageIter *iter, | ||
71 | const char *arg_name, | ||
72 | dbus_int16_t *value) | ||
73 | { | ||
74 | return pop_basic ( | ||
75 | message, | ||
76 | iter, | ||
77 | arg_name, | ||
78 | DBUS_TYPE_INT16, | ||
79 | (void *)value); | ||
80 | }; | ||
81 | |||
82 | DBusMessage * | ||
83 | GNUNET_DBUS_pop_uint16 ( | ||
84 | DBusMessage *message, | ||
85 | DBusMessageIter *iter, | ||
86 | const char *arg_name, | ||
87 | dbus_uint16_t *value) | ||
88 | { | ||
89 | return pop_basic ( | ||
90 | message, | ||
91 | iter, | ||
92 | arg_name, | ||
93 | DBUS_TYPE_UINT16, | ||
94 | (void *)value); | ||
95 | }; | ||
96 | |||
97 | DBusMessage * | ||
98 | GNUNET_DBUS_pop_int32 ( | ||
99 | DBusMessage *message, | ||
100 | DBusMessageIter *iter, | ||
101 | const char *arg_name, | ||
102 | dbus_int32_t *value) | ||
103 | { | ||
104 | return pop_basic ( | ||
105 | message, | ||
106 | iter, | ||
107 | arg_name, | ||
108 | DBUS_TYPE_INT32, | ||
109 | (void *)value); | ||
110 | }; | ||
111 | |||
112 | DBusMessage * | ||
113 | GNUNET_DBUS_pop_uint32 ( | ||
114 | DBusMessage *message, | ||
115 | DBusMessageIter *iter, | ||
116 | const char *arg_name, | ||
117 | dbus_uint32_t *value) | ||
118 | { | ||
119 | return pop_basic ( | ||
120 | message, | ||
121 | iter, | ||
122 | arg_name, | ||
123 | DBUS_TYPE_UINT32, | ||
124 | (void *)value); | ||
125 | }; | ||
126 | |||
127 | DBusMessage * | ||
128 | GNUNET_DBUS_pop_int64 ( | ||
129 | DBusMessage *message, | ||
130 | DBusMessageIter *iter, | ||
131 | const char *arg_name, | ||
132 | dbus_int64_t *value) | ||
133 | { | ||
134 | return pop_basic ( | ||
135 | message, | ||
136 | iter, | ||
137 | arg_name, | ||
138 | DBUS_TYPE_INT64, | ||
139 | (void *)value); | ||
140 | }; | ||
141 | |||
142 | DBusMessage * | ||
143 | GNUNET_DBUS_pop_uint64 ( | ||
144 | DBusMessage *message, | ||
145 | DBusMessageIter *iter, | ||
146 | const char *arg_name, | ||
147 | dbus_uint64_t *value) | ||
148 | { | ||
149 | return pop_basic ( | ||
150 | message, | ||
151 | iter, | ||
152 | arg_name, | ||
153 | DBUS_TYPE_UINT64, | ||
154 | (void *)value); | ||
155 | }; | ||
156 | |||
157 | DBusMessage * | ||
158 | GNUNET_DBUS_pop_double ( | ||
159 | DBusMessage *message, | ||
160 | DBusMessageIter *iter, | ||
161 | const char *arg_name, | ||
162 | double *value) | ||
163 | { | ||
164 | return pop_basic ( | ||
165 | message, | ||
166 | iter, | ||
167 | arg_name, | ||
168 | DBUS_TYPE_DOUBLE, | ||
169 | (void *)value); | ||
170 | }; | ||
171 | |||
172 | DBusMessage * | ||
173 | GNUNET_DBUS_pop_string ( | ||
174 | DBusMessage *message, | ||
175 | DBusMessageIter *iter, | ||
176 | const char *arg_name, | ||
177 | const char **value) | ||
178 | { | ||
179 | return pop_basic ( | ||
180 | message, | ||
181 | iter, | ||
182 | arg_name, | ||
183 | DBUS_TYPE_STRING, | ||
184 | (void *)value); | ||
185 | }; | ||
186 | |||
187 | DBusMessage * | ||
188 | GNUNET_DBUS_pop_object_path ( | ||
189 | DBusMessage *message, | ||
190 | DBusMessageIter *iter, | ||
191 | const char *arg_name, | ||
192 | const char **value) | ||
193 | { | ||
194 | return pop_basic ( | ||
195 | message, | ||
196 | iter, | ||
197 | arg_name, | ||
198 | DBUS_TYPE_OBJECT_PATH, | ||
199 | (void *)value); | ||
200 | }; | ||
201 | |||
202 | DBusMessage * | ||
203 | GNUNET_DBUS_pop_signature ( | ||
204 | DBusMessage *message, | ||
205 | DBusMessageIter *iter, | ||
206 | const char *arg_name, | ||
207 | const char **value) | ||
208 | { | ||
209 | return pop_basic ( | ||
210 | message, | ||
211 | iter, | ||
212 | arg_name, | ||
213 | DBUS_TYPE_SIGNATURE, | ||
214 | (void *)value); | ||
215 | }; | ||
216 | |||
217 | DBusMessage * | ||
218 | GNUNET_DBUS_pop_unix_fd ( | ||
219 | DBusMessage *message, | ||
220 | DBusMessageIter *iter, | ||
221 | const char *arg_name, | ||
222 | int *value) | ||
223 | { | ||
224 | return pop_basic ( | ||
225 | message, | ||
226 | iter, | ||
227 | arg_name, | ||
228 | DBUS_TYPE_UNIX_FD, | ||
229 | (void *)value); | ||
230 | }; | ||
231 | |||
232 | static DBusMessage * | ||
233 | pop_enter_container ( | ||
234 | DBusMessage *message, | ||
235 | DBusMessageIter *iter, | ||
236 | DBusMessageIter *iter_sub, | ||
237 | int type, | ||
238 | const char *arg_name) | ||
239 | { | ||
240 | int arg_type = dbus_message_iter_get_arg_type (iter); | ||
241 | if (type != arg_type) | ||
242 | { | ||
243 | return dbus_message_new_error_printf ( | ||
244 | message, | ||
245 | DBUS_ERROR_INVALID_ARGS, | ||
246 | "Bad argument for '%s'. Expected %s. Got %s", | ||
247 | arg_name, | ||
248 | GNUNET_DBUS_signature_typecode_to_string (type), | ||
249 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
250 | } | ||
251 | dbus_message_iter_recurse (iter, iter_sub); | ||
252 | dbus_message_iter_next (iter); | ||
253 | return NULL; | ||
254 | }; | ||
255 | |||
256 | DBusMessage * | ||
257 | GNUNET_DBUS_pop_enter_array ( | ||
258 | DBusMessage *message, | ||
259 | DBusMessageIter *iter, | ||
260 | DBusMessageIter *iter_sub, | ||
261 | const char *arg_name, | ||
262 | size_t *len) | ||
263 | { | ||
264 | if (len && dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY) | ||
265 | { | ||
266 | DBusMessageIter iter_calc_len; | ||
267 | dbus_message_iter_recurse (iter, &iter_calc_len); | ||
268 | *len = 0; | ||
269 | while (dbus_message_iter_get_arg_type (&iter_calc_len) != DBUS_TYPE_INVALID) | ||
270 | { | ||
271 | ++*len; | ||
272 | dbus_message_iter_next (&iter_calc_len); | ||
273 | }; | ||
274 | }; | ||
275 | return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_ARRAY, arg_name); | ||
276 | } | ||
277 | |||
278 | DBusMessage * | ||
279 | GNUNET_DBUS_pop_enter_struct ( | ||
280 | DBusMessage *message, | ||
281 | DBusMessageIter *iter, | ||
282 | DBusMessageIter *iter_sub, | ||
283 | const char *arg_name) | ||
284 | { | ||
285 | return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_STRUCT, arg_name); | ||
286 | } | ||
287 | |||
288 | DBusMessage * | ||
289 | GNUNET_DBUS_pop_enter_variant ( | ||
290 | DBusMessage *message, | ||
291 | DBusMessageIter *iter, | ||
292 | DBusMessageIter *iter_sub, | ||
293 | const char *arg_name) | ||
294 | { | ||
295 | return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_VARIANT, arg_name); | ||
296 | } | ||
297 | |||
298 | DBusMessage * | ||
299 | GNUNET_DBUS_pop_enter_dict_entry ( | ||
300 | DBusMessage *message, | ||
301 | DBusMessageIter *iter, | ||
302 | DBusMessageIter *iter_sub, | ||
303 | const char *arg_name) | ||
304 | { | ||
305 | return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_DICT_ENTRY, arg_name); | ||
306 | } | ||
307 | |||
308 | static DBusMessage * | ||
309 | pop_fixed_array ( | ||
310 | DBusMessage *message, | ||
311 | DBusMessageIter *iter, | ||
312 | const char *arg_name, | ||
313 | int expected_type, | ||
314 | void *value, | ||
315 | int *n_elements) | ||
316 | { | ||
317 | int arg_type = dbus_message_iter_get_arg_type (iter); | ||
318 | if (DBUS_TYPE_ARRAY != arg_type) | ||
319 | { | ||
320 | return dbus_message_new_error_printf ( | ||
321 | message, | ||
322 | DBUS_ERROR_INVALID_ARGS, | ||
323 | "Bad argument for '%s'. Expected array of %s. Got %s.", | ||
324 | arg_name, | ||
325 | GNUNET_DBUS_signature_typecode_to_string (expected_type), | ||
326 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
327 | }; | ||
328 | |||
329 | int element_type = dbus_message_iter_get_element_type (iter); | ||
330 | if (expected_type != element_type) | ||
331 | { | ||
332 | return dbus_message_new_error_printf ( | ||
333 | message, | ||
334 | DBUS_ERROR_INVALID_ARGS, | ||
335 | "Bad argument for '%s'. Expected array of %s. Got array of %s", | ||
336 | arg_name, | ||
337 | GNUNET_DBUS_signature_typecode_to_string (expected_type), | ||
338 | GNUNET_DBUS_signature_typecode_to_string (element_type)); | ||
339 | }; | ||
340 | |||
341 | DBusMessageIter iter_sub; | ||
342 | dbus_message_iter_recurse (iter, &iter_sub); | ||
343 | dbus_message_iter_get_fixed_array (&iter_sub, value, n_elements); | ||
344 | dbus_message_iter_next (iter); | ||
345 | |||
346 | return NULL; | ||
347 | }; | ||
348 | |||
349 | DBusMessage * | ||
350 | GNUNET_DBUS_pop_byte_array ( | ||
351 | DBusMessage *message, | ||
352 | DBusMessageIter *iter, | ||
353 | const char *arg_name, | ||
354 | const unsigned char **value, | ||
355 | int *n_elements) | ||
356 | { | ||
357 | return pop_fixed_array ( | ||
358 | message, | ||
359 | iter, | ||
360 | arg_name, | ||
361 | DBUS_TYPE_BYTE, | ||
362 | (void *)value, | ||
363 | n_elements); | ||
364 | }; | ||
365 | |||
366 | DBusMessage * | ||
367 | GNUNET_DBUS_pop_boolean_array ( | ||
368 | DBusMessage *message, | ||
369 | DBusMessageIter *iter, | ||
370 | const char *arg_name, | ||
371 | const dbus_bool_t **value, | ||
372 | int *n_elements) | ||
373 | { | ||
374 | return pop_fixed_array ( | ||
375 | message, | ||
376 | iter, | ||
377 | arg_name, | ||
378 | DBUS_TYPE_BOOLEAN, | ||
379 | (void *)value, | ||
380 | n_elements); | ||
381 | }; | ||
382 | |||
383 | DBusMessage * | ||
384 | GNUNET_DBUS_pop_int16_array ( | ||
385 | DBusMessage *message, | ||
386 | DBusMessageIter *iter, | ||
387 | const char *arg_name, | ||
388 | const int16_t **value, | ||
389 | int *n_elements) | ||
390 | { | ||
391 | return pop_fixed_array ( | ||
392 | message, | ||
393 | iter, | ||
394 | arg_name, | ||
395 | DBUS_TYPE_INT16, | ||
396 | (void *)value, | ||
397 | n_elements); | ||
398 | }; | ||
399 | |||
400 | DBusMessage * | ||
401 | GNUNET_DBUS_pop_uint16_array ( | ||
402 | DBusMessage *message, | ||
403 | DBusMessageIter *iter, | ||
404 | const char *arg_name, | ||
405 | const uint16_t **value, | ||
406 | int *n_elements) | ||
407 | { | ||
408 | return pop_fixed_array ( | ||
409 | message, | ||
410 | iter, | ||
411 | arg_name, | ||
412 | DBUS_TYPE_UINT16, | ||
413 | (void *)value, | ||
414 | n_elements); | ||
415 | }; | ||
416 | |||
417 | DBusMessage * | ||
418 | GNUNET_DBUS_pop_int32_array ( | ||
419 | DBusMessage *message, | ||
420 | DBusMessageIter *iter, | ||
421 | const char *arg_name, | ||
422 | const int32_t **value, | ||
423 | int *n_elements) | ||
424 | { | ||
425 | return pop_fixed_array ( | ||
426 | message, | ||
427 | iter, | ||
428 | arg_name, | ||
429 | DBUS_TYPE_INT32, | ||
430 | (void *)value, | ||
431 | n_elements); | ||
432 | }; | ||
433 | |||
434 | DBusMessage * | ||
435 | GNUNET_DBUS_pop_uint32_array ( | ||
436 | DBusMessage *message, | ||
437 | DBusMessageIter *iter, | ||
438 | const char *arg_name, | ||
439 | const uint32_t **value, | ||
440 | int *n_elements) | ||
441 | { | ||
442 | return pop_fixed_array ( | ||
443 | message, | ||
444 | iter, | ||
445 | arg_name, | ||
446 | DBUS_TYPE_UINT32, | ||
447 | (void *)value, | ||
448 | n_elements); | ||
449 | }; | ||
450 | |||
451 | DBusMessage * | ||
452 | GNUNET_DBUS_pop_int64_array ( | ||
453 | DBusMessage *message, | ||
454 | DBusMessageIter *iter, | ||
455 | const char *arg_name, | ||
456 | const int64_t **value, | ||
457 | int *n_elements) | ||
458 | { | ||
459 | return pop_fixed_array ( | ||
460 | message, | ||
461 | iter, | ||
462 | arg_name, | ||
463 | DBUS_TYPE_INT64, | ||
464 | (void *)value, | ||
465 | n_elements); | ||
466 | }; | ||
467 | |||
468 | DBusMessage * | ||
469 | GNUNET_DBUS_pop_uint64_array ( | ||
470 | DBusMessage *message, | ||
471 | DBusMessageIter *iter, | ||
472 | const char *arg_name, | ||
473 | const uint64_t **value, | ||
474 | int *n_elements) | ||
475 | { | ||
476 | return pop_fixed_array ( | ||
477 | message, | ||
478 | iter, | ||
479 | arg_name, | ||
480 | DBUS_TYPE_UINT64, | ||
481 | (void *)value, | ||
482 | n_elements); | ||
483 | }; | ||
484 | |||
485 | DBusMessage * | ||
486 | GNUNET_DBUS_pop_double_array ( | ||
487 | DBusMessage *message, | ||
488 | DBusMessageIter *iter, | ||
489 | const char *arg_name, | ||
490 | const double **value, | ||
491 | int *n_elements) | ||
492 | { | ||
493 | return pop_fixed_array ( | ||
494 | message, | ||
495 | iter, | ||
496 | arg_name, | ||
497 | DBUS_TYPE_DOUBLE, | ||
498 | (void *)value, | ||
499 | n_elements); | ||
500 | }; | ||
501 | |||
502 | /* | ||
503 | * bitfield enums can be sent across the wire in either their integer form (as | ||
504 | * an array of bit flags) or as an array of strings. Sending an int is more | ||
505 | * efficient and is what libraries built around the DBus API would use, people | ||
506 | * using the DBus API directly may want to pass human-readable strings for | ||
507 | * convenience. | ||
508 | */ | ||
509 | DBusMessage * | ||
510 | GNUNET_DBUS_pop_bitfield ( | ||
511 | DBusMessage *message, | ||
512 | DBusMessageIter *iter, | ||
513 | const char *arg_name, | ||
514 | int *value, | ||
515 | const struct GNUNET_DBUS_StringEnumPair *fields) | ||
516 | { | ||
517 | DBusMessageIter iter_sub; | ||
518 | DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
519 | if (ret) | ||
520 | return ret; | ||
521 | |||
522 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
523 | switch (arg_type) | ||
524 | { | ||
525 | case DBUS_TYPE_ARRAY: { | ||
526 | int element_type = dbus_message_iter_get_element_type (&iter_sub); | ||
527 | if (DBUS_TYPE_STRING != element_type) | ||
528 | { | ||
529 | return dbus_message_new_error_printf ( | ||
530 | message, | ||
531 | DBUS_ERROR_INVALID_ARGS, | ||
532 | "Bad argument for '%s'. Variant should contain a uint32 or an array of strings.", | ||
533 | arg_name); | ||
534 | }; | ||
535 | DBusMessageIter iter_sub_sub; | ||
536 | dbus_message_iter_recurse (&iter_sub, &iter_sub_sub); | ||
537 | *value = 0; | ||
538 | while (dbus_message_iter_get_arg_type (&iter_sub_sub) != DBUS_TYPE_INVALID) | ||
539 | { | ||
540 | char *option; | ||
541 | dbus_message_iter_get_basic (&iter_sub_sub, &option); | ||
542 | const struct GNUNET_DBUS_StringEnumPair *field; | ||
543 | for (field = fields; field->name; field++) | ||
544 | { | ||
545 | if (! strcmp (field->name, option)) | ||
546 | { | ||
547 | *value |= field->value; | ||
548 | break; | ||
549 | }; | ||
550 | }; | ||
551 | if (! field->name) | ||
552 | { | ||
553 | char *errmsg; | ||
554 | GNUNET_asprintf (&errmsg, "Bad argument for '%s'. Unrecognised option '%s'. Valid options are [", arg_name, option); | ||
555 | for (field = fields; field->name; field++) | ||
556 | { | ||
557 | char *errmsg_new; | ||
558 | GNUNET_asprintf (&errmsg_new, "%s'%s'%s", errmsg, field->name, (field + 1)->name ? ", " : "]."); | ||
559 | GNUNET_free (errmsg); | ||
560 | errmsg = errmsg_new; | ||
561 | }; | ||
562 | DBusMessage *ret = dbus_message_new_error ( | ||
563 | message, | ||
564 | DBUS_ERROR_INVALID_ARGS, | ||
565 | errmsg); | ||
566 | GNUNET_free (errmsg); | ||
567 | return ret; | ||
568 | }; | ||
569 | dbus_message_iter_next (&iter_sub_sub); | ||
570 | }; | ||
571 | GNUNET_DBUS_message_set_pretty (message, true); | ||
572 | return NULL; | ||
573 | }; | ||
574 | case DBUS_TYPE_UINT32: { | ||
575 | uint32_t flags; | ||
576 | dbus_message_iter_get_basic (&iter_sub, &flags); | ||
577 | *value = (int)flags; | ||
578 | return NULL; | ||
579 | }; | ||
580 | default: | ||
581 | return dbus_message_new_error_printf ( | ||
582 | message, | ||
583 | DBUS_ERROR_INVALID_ARGS, | ||
584 | "Bad argument for '%s'. Variant contains a %s. Should contain a uint32 or array of strings.", | ||
585 | arg_name); | ||
586 | }; | ||
587 | }; | ||
588 | |||
589 | DBusMessage * | ||
590 | GNUNET_DBUS_pop_enum ( | ||
591 | DBusMessage *message, | ||
592 | DBusMessageIter *iter, | ||
593 | const char *arg_name, | ||
594 | int *value, | ||
595 | const struct GNUNET_DBUS_StringEnumPair *names) | ||
596 | { | ||
597 | DBusMessageIter iter_sub; | ||
598 | DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
599 | if (ret) | ||
600 | return ret; | ||
601 | |||
602 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
603 | switch (arg_type) | ||
604 | { | ||
605 | case DBUS_TYPE_STRING: { | ||
606 | char *option; | ||
607 | dbus_message_iter_get_basic (&iter_sub, &option); | ||
608 | const struct GNUNET_DBUS_StringEnumPair *name; | ||
609 | for (name = names; name->name; name++) | ||
610 | { | ||
611 | if (! strcmp (name->name, option)) | ||
612 | { | ||
613 | *value = name->value; | ||
614 | return NULL; | ||
615 | }; | ||
616 | }; | ||
617 | char *errmsg; | ||
618 | GNUNET_asprintf (&errmsg, "Bad argument for '%s'. Unrecognised option '%s'. Valid options are [", arg_name, option); | ||
619 | for (name = names; name->name; name++) | ||
620 | { | ||
621 | char *errmsg_new; | ||
622 | GNUNET_asprintf (&errmsg_new, "%s'%s'%s", errmsg, name->name, (name + 1)->name ? ", " : "]."); | ||
623 | GNUNET_free (errmsg); | ||
624 | errmsg = errmsg_new; | ||
625 | }; | ||
626 | |||
627 | DBusMessage *ret = dbus_message_new_error ( | ||
628 | message, | ||
629 | DBUS_ERROR_INVALID_ARGS, | ||
630 | errmsg); | ||
631 | GNUNET_free (errmsg); | ||
632 | return ret; | ||
633 | }; | ||
634 | case DBUS_TYPE_UINT32: { | ||
635 | uint32_t option; | ||
636 | dbus_message_iter_get_basic (&iter_sub, &option); | ||
637 | *value = (int)option; | ||
638 | return NULL; | ||
639 | }; | ||
640 | default: | ||
641 | return dbus_message_new_error_printf ( | ||
642 | message, | ||
643 | DBUS_ERROR_INVALID_ARGS, | ||
644 | "Bad argument for '%s'. Variant contains a %s. Should contain a uint32 or strings.", | ||
645 | arg_name, | ||
646 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
647 | }; | ||
648 | }; | ||
649 | |||
650 | DBusMessage * | ||
651 | GNUNET_DBUS_pop_hashcode ( | ||
652 | DBusMessage *message, | ||
653 | DBusMessageIter *iter, | ||
654 | const char *arg_name, | ||
655 | struct GNUNET_HashCode *value) | ||
656 | { | ||
657 | DBusMessageIter iter_sub; | ||
658 | DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
659 | if (ret) | ||
660 | return ret; | ||
661 | |||
662 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
663 | switch (arg_type) | ||
664 | { | ||
665 | case DBUS_TYPE_STRING: { | ||
666 | char *encoded; | ||
667 | dbus_message_iter_get_basic (&iter_sub, &encoded); | ||
668 | int success = GNUNET_CRYPTO_hash_from_string2 (encoded, strlen (encoded), value); | ||
669 | if (GNUNET_OK != success) | ||
670 | { | ||
671 | return dbus_message_new_error_printf ( | ||
672 | message, | ||
673 | DBUS_ERROR_INVALID_ARGS, | ||
674 | "Bad argument for '%s'. Malformed hash string. GNUNET_CRYPTO_hash_from_string2 returned %d", | ||
675 | arg_name, | ||
676 | success); | ||
677 | }; | ||
678 | GNUNET_DBUS_message_set_pretty (message, true); | ||
679 | return NULL; | ||
680 | } | ||
681 | case DBUS_TYPE_ARRAY: { | ||
682 | DBusMessageIter iter_sub_sub; | ||
683 | unsigned char *data; | ||
684 | int n_elements; | ||
685 | int element_type = dbus_message_iter_get_element_type (&iter_sub); | ||
686 | if (DBUS_TYPE_BYTE != element_type) | ||
687 | { | ||
688 | return dbus_message_new_error_printf ( | ||
689 | message, | ||
690 | DBUS_ERROR_INVALID_ARGS, | ||
691 | "Bad argument for '%s'. Variant contains an array of %s. Should contain a base32 encoded string or array of 64 bytes.", | ||
692 | arg_name, | ||
693 | GNUNET_DBUS_signature_typecode_to_string (element_type)); | ||
694 | }; | ||
695 | dbus_message_iter_recurse (&iter_sub, &iter_sub_sub); | ||
696 | dbus_message_iter_get_fixed_array (&iter_sub_sub, &data, &n_elements); | ||
697 | if (sizeof (value->bits) != n_elements) | ||
698 | { | ||
699 | return dbus_message_new_error_printf ( | ||
700 | message, | ||
701 | DBUS_ERROR_INVALID_ARGS, | ||
702 | "Bad argument for '%s'. Hash code consists of 64 bytes (512 bits). Array contains %d bytes.", | ||
703 | arg_name, | ||
704 | n_elements); | ||
705 | }; | ||
706 | memcpy (value->bits, data, n_elements); | ||
707 | return NULL; | ||
708 | }; | ||
709 | default: | ||
710 | return dbus_message_new_error_printf ( | ||
711 | message, | ||
712 | DBUS_ERROR_INVALID_ARGS, | ||
713 | "Bad argument for '%s'. Variant contains a %s. Should contain a base32 encoded string or array of 64 bytes.", | ||
714 | arg_name, | ||
715 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
716 | }; | ||
717 | } | ||
718 | |||
719 | DBusMessage * | ||
720 | GNUNET_DBUS_pop_peer_identity ( | ||
721 | DBusMessage *message, | ||
722 | DBusMessageIter *iter, | ||
723 | const char *arg_name, | ||
724 | struct GNUNET_PeerIdentity *value) | ||
725 | { | ||
726 | DBusMessageIter iter_sub; | ||
727 | DBusMessage *ret = GNUNET_DBUS_pop_enter_struct (message, iter, &iter_sub, arg_name); | ||
728 | if (ret) | ||
729 | return ret; | ||
730 | |||
731 | return GNUNET_CRYPTO_DBUS_pop_eddsa_public_key (message, &iter_sub, "public_key", &value->public_key); | ||
732 | } | ||
733 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_push.c b/src/lib/common/gnunet_dbus_lib_push.c new file mode 100644 index 0000000..1cb455e --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_push.c | |||
@@ -0,0 +1,510 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <stdbool.h> | ||
4 | |||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_strings_lib.h> | ||
8 | |||
9 | #include "gnunet_dbus_lib.h" | ||
10 | #include "gnunet_crypto_dbus_lib.h" | ||
11 | |||
12 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-push", __VA_ARGS__) | ||
13 | |||
14 | static void | ||
15 | push_basic ( | ||
16 | DBusMessage *message, | ||
17 | DBusMessageIter *iter, | ||
18 | int type, | ||
19 | const void *value) | ||
20 | { | ||
21 | (void)message; | ||
22 | bool success = dbus_message_iter_append_basic (iter, type, value); | ||
23 | if (! success) | ||
24 | { | ||
25 | LOG (GNUNET_ERROR_TYPE_ERROR, "Ran out of memory in dbus_message_iter_append_basic\n"); | ||
26 | GNUNET_abort_ (); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | void | ||
31 | GNUNET_DBUS_push_byte ( | ||
32 | DBusMessage *message, | ||
33 | DBusMessageIter *iter, | ||
34 | const unsigned char *value) | ||
35 | { | ||
36 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing byte\n"); | ||
37 | push_basic (message, iter, DBUS_TYPE_BYTE, value); | ||
38 | } | ||
39 | |||
40 | void | ||
41 | GNUNET_DBUS_push_boolean ( | ||
42 | DBusMessage *message, | ||
43 | DBusMessageIter *iter, | ||
44 | const dbus_bool_t *value) | ||
45 | { | ||
46 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing boolean\n"); | ||
47 | push_basic (message, iter, DBUS_TYPE_BOOLEAN, value); | ||
48 | } | ||
49 | |||
50 | void | ||
51 | GNUNET_DBUS_push_int16 ( | ||
52 | DBusMessage *message, | ||
53 | DBusMessageIter *iter, | ||
54 | const dbus_int16_t *value) | ||
55 | { | ||
56 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing int16\n"); | ||
57 | push_basic (message, iter, DBUS_TYPE_INT16, value); | ||
58 | } | ||
59 | |||
60 | void | ||
61 | GNUNET_DBUS_push_uint16 ( | ||
62 | DBusMessage *message, | ||
63 | DBusMessageIter *iter, | ||
64 | const dbus_uint16_t *value) | ||
65 | { | ||
66 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing uint16\n"); | ||
67 | push_basic (message, iter, DBUS_TYPE_UINT16, value); | ||
68 | } | ||
69 | |||
70 | void | ||
71 | GNUNET_DBUS_push_int32 ( | ||
72 | DBusMessage *message, | ||
73 | DBusMessageIter *iter, | ||
74 | const dbus_int32_t *value) | ||
75 | { | ||
76 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing int32\n"); | ||
77 | push_basic (message, iter, DBUS_TYPE_INT32, value); | ||
78 | } | ||
79 | |||
80 | void | ||
81 | GNUNET_DBUS_push_uint32 ( | ||
82 | DBusMessage *message, | ||
83 | DBusMessageIter *iter, | ||
84 | const dbus_uint32_t *value) | ||
85 | { | ||
86 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing uint32\n"); | ||
87 | push_basic (message, iter, DBUS_TYPE_UINT32, value); | ||
88 | } | ||
89 | |||
90 | void | ||
91 | GNUNET_DBUS_push_int64 ( | ||
92 | DBusMessage *message, | ||
93 | DBusMessageIter *iter, | ||
94 | const dbus_int64_t *value) | ||
95 | { | ||
96 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing int64\n"); | ||
97 | push_basic (message, iter, DBUS_TYPE_INT64, value); | ||
98 | } | ||
99 | |||
100 | void | ||
101 | GNUNET_DBUS_push_uint64 ( | ||
102 | DBusMessage *message, | ||
103 | DBusMessageIter *iter, | ||
104 | const dbus_uint64_t *value) | ||
105 | { | ||
106 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing uint64\n"); | ||
107 | push_basic (message, iter, DBUS_TYPE_UINT64, value); | ||
108 | } | ||
109 | |||
110 | void | ||
111 | GNUNET_DBUS_push_double ( | ||
112 | DBusMessage *message, | ||
113 | DBusMessageIter *iter, | ||
114 | const double *value) | ||
115 | { | ||
116 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing double\n"); | ||
117 | push_basic (message, iter, DBUS_TYPE_DOUBLE, value); | ||
118 | } | ||
119 | |||
120 | void | ||
121 | GNUNET_DBUS_push_string ( | ||
122 | DBusMessage *message, | ||
123 | DBusMessageIter *iter, | ||
124 | const char *const *value) | ||
125 | { | ||
126 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing string\n"); | ||
127 | push_basic (message, iter, DBUS_TYPE_STRING, value); | ||
128 | } | ||
129 | |||
130 | void | ||
131 | GNUNET_DBUS_push_object_path ( | ||
132 | DBusMessage *message, | ||
133 | DBusMessageIter *iter, | ||
134 | const struct GNUNET_DBUS_ObjectPath *path) | ||
135 | { | ||
136 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing object path\n"); | ||
137 | char *path_as_string = GNUNET_DBUS_object_path_to_string (path); | ||
138 | push_basic (message, iter, DBUS_TYPE_OBJECT_PATH, &path_as_string); | ||
139 | GNUNET_free (path_as_string); | ||
140 | } | ||
141 | |||
142 | void | ||
143 | GNUNET_DBUS_push_signature ( | ||
144 | DBusMessage *message, | ||
145 | DBusMessageIter *iter, | ||
146 | const char *const *value) | ||
147 | { | ||
148 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing signature\n"); | ||
149 | push_basic (message, iter, DBUS_TYPE_SIGNATURE, value); | ||
150 | } | ||
151 | |||
152 | void | ||
153 | GNUNET_DBUS_push_unix_fd ( | ||
154 | DBusMessage *message, | ||
155 | DBusMessageIter *iter, | ||
156 | const int *value) | ||
157 | { | ||
158 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing unix fd\n"); | ||
159 | push_basic (message, iter, DBUS_TYPE_UNIX_FD, value); | ||
160 | } | ||
161 | |||
162 | static void | ||
163 | push_open_container ( | ||
164 | DBusMessage *message, | ||
165 | DBusMessageIter *iter, | ||
166 | DBusMessageIter *iter_sub, | ||
167 | int type, | ||
168 | const char *signature) | ||
169 | { | ||
170 | (void)message; | ||
171 | bool success = dbus_message_iter_open_container (iter, type, signature, iter_sub); | ||
172 | if (! success) | ||
173 | { | ||
174 | LOG (GNUNET_ERROR_TYPE_ERROR, "Ran out of memory in dbus_message_iter_open_container\n"); | ||
175 | GNUNET_abort_ (); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | void | ||
180 | GNUNET_DBUS_push_open_array ( | ||
181 | DBusMessage *message, | ||
182 | DBusMessageIter *iter, | ||
183 | DBusMessageIter *iter_sub, | ||
184 | const char *signature) | ||
185 | { | ||
186 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Opening array\n"); | ||
187 | push_open_container (message, iter, iter_sub, DBUS_TYPE_ARRAY, signature); | ||
188 | } | ||
189 | |||
190 | void | ||
191 | GNUNET_DBUS_push_open_struct ( | ||
192 | DBusMessage *message, | ||
193 | DBusMessageIter *iter, | ||
194 | DBusMessageIter *iter_sub) | ||
195 | { | ||
196 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Opening struct\n"); | ||
197 | push_open_container (message, iter, iter_sub, DBUS_TYPE_STRUCT, NULL); | ||
198 | } | ||
199 | |||
200 | void | ||
201 | GNUNET_DBUS_push_open_variant ( | ||
202 | DBusMessage *message, | ||
203 | DBusMessageIter *iter, | ||
204 | DBusMessageIter *iter_sub, | ||
205 | const char *signature) | ||
206 | { | ||
207 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Opening variant\n"); | ||
208 | push_open_container (message, iter, iter_sub, DBUS_TYPE_VARIANT, signature); | ||
209 | } | ||
210 | |||
211 | void | ||
212 | GNUNET_DBUS_push_open_dict_entry ( | ||
213 | DBusMessage *message, | ||
214 | DBusMessageIter *iter, | ||
215 | DBusMessageIter *iter_sub) | ||
216 | { | ||
217 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Opening dict entry\n"); | ||
218 | push_open_container (message, iter, iter_sub, DBUS_TYPE_DICT_ENTRY, NULL); | ||
219 | } | ||
220 | |||
221 | static void | ||
222 | push_close_container ( | ||
223 | DBusMessage *message, | ||
224 | DBusMessageIter *iter, | ||
225 | DBusMessageIter *iter_sub) | ||
226 | { | ||
227 | (void)message; | ||
228 | bool success = dbus_message_iter_close_container (iter, iter_sub); | ||
229 | if (! success) | ||
230 | { | ||
231 | LOG (GNUNET_ERROR_TYPE_ERROR, "Ran out of memory in dbus_message_iter_close_container\n"); | ||
232 | GNUNET_abort_ (); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | void | ||
237 | GNUNET_DBUS_push_close_array ( | ||
238 | DBusMessage *message, | ||
239 | DBusMessageIter *iter, | ||
240 | DBusMessageIter *iter_sub) | ||
241 | { | ||
242 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing array\n"); | ||
243 | push_close_container (message, iter, iter_sub); | ||
244 | } | ||
245 | |||
246 | void | ||
247 | GNUNET_DBUS_push_close_struct ( | ||
248 | DBusMessage *message, | ||
249 | DBusMessageIter *iter, | ||
250 | DBusMessageIter *iter_sub) | ||
251 | { | ||
252 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing struct\n"); | ||
253 | push_close_container (message, iter, iter_sub); | ||
254 | } | ||
255 | |||
256 | void | ||
257 | GNUNET_DBUS_push_close_variant ( | ||
258 | DBusMessage *message, | ||
259 | DBusMessageIter *iter, | ||
260 | DBusMessageIter *iter_sub) | ||
261 | { | ||
262 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing variant\n"); | ||
263 | push_close_container (message, iter, iter_sub); | ||
264 | } | ||
265 | |||
266 | void | ||
267 | GNUNET_DBUS_push_close_dict_entry ( | ||
268 | DBusMessage *message, | ||
269 | DBusMessageIter *iter, | ||
270 | DBusMessageIter *iter_sub) | ||
271 | { | ||
272 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing dict entry\n"); | ||
273 | push_close_container (message, iter, iter_sub); | ||
274 | } | ||
275 | |||
276 | static void | ||
277 | push_fixed_array ( | ||
278 | DBusMessage *message, | ||
279 | DBusMessageIter *iter, | ||
280 | int type, | ||
281 | const void *value, | ||
282 | size_t value_count) | ||
283 | { | ||
284 | char sig[2] = { (char)type, '\0' }; | ||
285 | DBusMessageIter iter_sub; | ||
286 | |||
287 | GNUNET_DBUS_push_open_array (message, iter, &iter_sub, sig); | ||
288 | bool success = dbus_message_iter_append_fixed_array (&iter_sub, type, value, (int)value_count); | ||
289 | if (! success) | ||
290 | { | ||
291 | LOG (GNUNET_ERROR_TYPE_ERROR, "Ran out of memory in dbus_message_iter_push_fixed_array\n"); | ||
292 | GNUNET_abort_ (); | ||
293 | } | ||
294 | GNUNET_DBUS_push_close_array (message, iter, &iter_sub); | ||
295 | } | ||
296 | |||
297 | void | ||
298 | GNUNET_DBUS_push_byte_array ( | ||
299 | DBusMessage *message, | ||
300 | DBusMessageIter *iter, | ||
301 | const unsigned char *value, | ||
302 | size_t value_count) | ||
303 | { | ||
304 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing byte array\n"); | ||
305 | push_fixed_array (message, iter, DBUS_TYPE_BYTE, &value, value_count); | ||
306 | } | ||
307 | |||
308 | void | ||
309 | GNUNET_DBUS_push_boolean_array ( | ||
310 | DBusMessage *message, | ||
311 | DBusMessageIter *iter, | ||
312 | const dbus_bool_t *value, | ||
313 | size_t value_count) | ||
314 | { | ||
315 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing boolean array\n"); | ||
316 | push_fixed_array (message, iter, DBUS_TYPE_BOOLEAN, &value, value_count); | ||
317 | } | ||
318 | |||
319 | void | ||
320 | GNUNET_DBUS_push_int16_array ( | ||
321 | DBusMessage *message, | ||
322 | DBusMessageIter *iter, | ||
323 | const dbus_int16_t *value, | ||
324 | size_t value_count) | ||
325 | { | ||
326 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing int16 array\n"); | ||
327 | push_fixed_array (message, iter, DBUS_TYPE_INT16, &value, value_count); | ||
328 | } | ||
329 | |||
330 | void | ||
331 | GNUNET_DBUS_push_uint16_array ( | ||
332 | DBusMessage *message, | ||
333 | DBusMessageIter *iter, | ||
334 | const dbus_uint16_t *value, | ||
335 | size_t value_count) | ||
336 | { | ||
337 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing uint16 array\n"); | ||
338 | push_fixed_array (message, iter, DBUS_TYPE_UINT16, &value, value_count); | ||
339 | } | ||
340 | |||
341 | void | ||
342 | GNUNET_DBUS_push_int32_array ( | ||
343 | DBusMessage *message, | ||
344 | DBusMessageIter *iter, | ||
345 | const unsigned char *value, | ||
346 | size_t value_count) | ||
347 | { | ||
348 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing int32 array\n"); | ||
349 | push_fixed_array (message, iter, DBUS_TYPE_INT32, &value, value_count); | ||
350 | } | ||
351 | |||
352 | void | ||
353 | GNUNET_DBUS_push_uint32_array ( | ||
354 | DBusMessage *message, | ||
355 | DBusMessageIter *iter, | ||
356 | const unsigned char *value, | ||
357 | size_t value_count) | ||
358 | { | ||
359 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing uint32 array\n"); | ||
360 | push_fixed_array (message, iter, DBUS_TYPE_UINT32, &value, value_count); | ||
361 | } | ||
362 | |||
363 | void | ||
364 | GNUNET_DBUS_push_int64_array ( | ||
365 | DBusMessage *message, | ||
366 | DBusMessageIter *iter, | ||
367 | const unsigned char *value, | ||
368 | size_t value_count) | ||
369 | { | ||
370 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing int64 array\n"); | ||
371 | push_fixed_array (message, iter, DBUS_TYPE_INT64, &value, value_count); | ||
372 | } | ||
373 | |||
374 | void | ||
375 | GNUNET_DBUS_push_uint64_array ( | ||
376 | DBusMessage *message, | ||
377 | DBusMessageIter *iter, | ||
378 | const unsigned char *value, | ||
379 | size_t value_count) | ||
380 | { | ||
381 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing uint64 array\n"); | ||
382 | push_fixed_array (message, iter, DBUS_TYPE_UINT64, &value, value_count); | ||
383 | } | ||
384 | |||
385 | void | ||
386 | GNUNET_DBUS_push_double_array ( | ||
387 | DBusMessage *message, | ||
388 | DBusMessageIter *iter, | ||
389 | const unsigned char *value, | ||
390 | size_t value_count) | ||
391 | { | ||
392 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing double array\n"); | ||
393 | push_fixed_array (message, iter, DBUS_TYPE_DOUBLE, &value, value_count); | ||
394 | } | ||
395 | |||
396 | void | ||
397 | GNUNET_DBUS_push_bitfield ( | ||
398 | DBusMessage *message, | ||
399 | DBusMessageIter *iter, | ||
400 | const int *value, | ||
401 | const struct GNUNET_DBUS_StringEnumPair *fields) | ||
402 | { | ||
403 | DBusMessageIter iter_sub; | ||
404 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
405 | { | ||
406 | DBusMessageIter iter_sub_sub; | ||
407 | |||
408 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_ARRAY (GNUNET_DBUS_SIGNATURE_STRING)); | ||
409 | GNUNET_DBUS_push_open_array (message, &iter_sub, &iter_sub_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
410 | const struct GNUNET_DBUS_StringEnumPair *field; | ||
411 | for (field = fields; field->name; field++) | ||
412 | { | ||
413 | if ((*value & field->value) == field->value) | ||
414 | GNUNET_DBUS_push_string (message, &iter_sub_sub, &field->name); | ||
415 | }; | ||
416 | GNUNET_DBUS_push_close_array (message, &iter_sub, &iter_sub_sub); | ||
417 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
418 | } | ||
419 | else | ||
420 | { | ||
421 | uint32_t push_value = (uint32_t)*value; | ||
422 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_UINT32); | ||
423 | GNUNET_DBUS_push_uint32 (message, &iter_sub, &push_value); | ||
424 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
425 | }; | ||
426 | }; | ||
427 | |||
428 | void | ||
429 | GNUNET_DBUS_push_enum ( | ||
430 | DBusMessage *message, | ||
431 | DBusMessageIter *iter, | ||
432 | const int *value, | ||
433 | const struct GNUNET_DBUS_StringEnumPair *names) | ||
434 | { | ||
435 | DBusMessageIter iter_sub; | ||
436 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
437 | { | ||
438 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
439 | const struct GNUNET_DBUS_StringEnumPair *name; | ||
440 | for (name = names; name->name; name++) | ||
441 | { | ||
442 | if (name->value == *value) | ||
443 | { | ||
444 | GNUNET_DBUS_push_string (message, &iter_sub, &name->name); | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
449 | } | ||
450 | else | ||
451 | { | ||
452 | uint32_t push_value = (uint32_t)*value; | ||
453 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_UINT32); | ||
454 | GNUNET_DBUS_push_uint32 (message, &iter_sub, &push_value); | ||
455 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
456 | }; | ||
457 | }; | ||
458 | |||
459 | void | ||
460 | GNUNET_DBUS_push_data ( | ||
461 | DBusMessage *message, | ||
462 | DBusMessageIter *iter, | ||
463 | const void *value, | ||
464 | size_t value_size) | ||
465 | { | ||
466 | DBusMessageIter iter_sub; | ||
467 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
468 | { | ||
469 | size_t string_size = (value_size * 8 + 4) / 5 + 1; | ||
470 | char *string = GNUNET_malloc (string_size); | ||
471 | char *end = GNUNET_STRINGS_data_to_string (value, value_size, string, string_size); | ||
472 | *end = '\0'; | ||
473 | const char *string_const = string; | ||
474 | |||
475 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
476 | GNUNET_DBUS_push_string (message, &iter_sub, &string_const); | ||
477 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
478 | GNUNET_free (string); | ||
479 | } | ||
480 | else | ||
481 | { | ||
482 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_ARRAY (GNUNET_DBUS_SIGNATURE_BYTE)); | ||
483 | GNUNET_DBUS_push_byte_array (message, &iter_sub, value, value_size); | ||
484 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
485 | }; | ||
486 | } | ||
487 | |||
488 | void | ||
489 | GNUNET_DBUS_push_hashcode ( | ||
490 | DBusMessage *message, | ||
491 | DBusMessageIter *iter, | ||
492 | const struct GNUNET_HashCode *value) | ||
493 | { | ||
494 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing GNUNET_HashCode\n"); | ||
495 | GNUNET_DBUS_push_data (message, iter, value->bits, sizeof (value->bits)); | ||
496 | } | ||
497 | |||
498 | void | ||
499 | GNUNET_DBUS_push_peer_identity ( | ||
500 | DBusMessage *message, | ||
501 | DBusMessageIter *iter, | ||
502 | const struct GNUNET_PeerIdentity *value) | ||
503 | { | ||
504 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing GNUNET_PeerIdentity\n"); | ||
505 | DBusMessageIter iter_sub; | ||
506 | GNUNET_DBUS_push_open_struct (message, iter, &iter_sub); | ||
507 | GNUNET_CRYPTO_DBUS_push_eddsa_public_key (message, &iter_sub, &value->public_key); | ||
508 | GNUNET_DBUS_push_close_struct (message, iter, &iter_sub); | ||
509 | } | ||
510 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_service.c b/src/lib/common/gnunet_dbus_lib_service.c new file mode 100644 index 0000000..2151613 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_service.c | |||
@@ -0,0 +1,686 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <stdbool.h> | ||
4 | #include <dbus/dbus.h> | ||
5 | |||
6 | #include <gnunet/platform.h> | ||
7 | #include <gnunet/gnunet_common.h> | ||
8 | #include <gnunet/gnunet_scheduler_lib.h> | ||
9 | #include <gnunet/gnunet_container_lib.h> | ||
10 | |||
11 | #include "gnunet_dbus_lib.h" | ||
12 | |||
13 | #include "watch.h" | ||
14 | #include "timeout.h" | ||
15 | |||
16 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-service", __VA_ARGS__) | ||
17 | |||
18 | struct GNUNET_DBUS_Service | ||
19 | { | ||
20 | #if 0 | ||
21 | struct GNUNET_DBUS_ObjectIterator *objects_front; | ||
22 | struct GNUNET_DBUS_ObjectIterator *objects_back; | ||
23 | #else | ||
24 | struct GNUNET_DBUS_Object *root_object; | ||
25 | #endif | ||
26 | |||
27 | DBusConnection *dbus_connection; | ||
28 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
29 | |||
30 | char *gnunet_name; | ||
31 | char *well_known_name; | ||
32 | |||
33 | /* | ||
34 | * Linked list of watches | ||
35 | */ | ||
36 | struct WatchIter *watches_front; | ||
37 | struct WatchIter *watches_back; | ||
38 | |||
39 | /* | ||
40 | * Linked list of timeouts | ||
41 | */ | ||
42 | struct TimeoutIter *timeouts_front; | ||
43 | struct TimeoutIter *timeouts_back; | ||
44 | |||
45 | /* | ||
46 | * Linked list of clients | ||
47 | */ | ||
48 | struct GNUNET_DBUS_ClientIterator *clients_front; | ||
49 | struct GNUNET_DBUS_ClientIterator *clients_back; | ||
50 | |||
51 | GNUNET_DBUS_ClientConnectsHandler client_connects; | ||
52 | GNUNET_DBUS_ClientDisconnectsHandler client_disconnects; | ||
53 | |||
54 | unsigned ref_count; | ||
55 | }; | ||
56 | |||
57 | static dbus_int32_t service_slot_id () | ||
58 | { | ||
59 | static dbus_int32_t id = -1; | ||
60 | if (-1 == id) | ||
61 | { | ||
62 | dbus_bool_t succ = dbus_connection_allocate_data_slot (&id); | ||
63 | if (! succ || -1 == id) | ||
64 | { | ||
65 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_connection_allocate_data_slot failed. id == %lld\n", (long long)id); | ||
66 | GNUNET_abort_ (); | ||
67 | }; | ||
68 | }; | ||
69 | |||
70 | return id; | ||
71 | }; | ||
72 | |||
73 | /* | ||
74 | * Called by DBus when it has a new watch that it wants us to watch. | ||
75 | * | ||
76 | * @param watch The DBus watch, created and passed to us by DBus. | ||
77 | * @param data the GNUNET_DBUS_Service we passed to dbus_connection_set_watch_functions | ||
78 | * @return true on success, false on an unrecoverable error. | ||
79 | */ | ||
80 | static dbus_bool_t | ||
81 | watch_add ( | ||
82 | DBusWatch *watch, | ||
83 | void *data) | ||
84 | { | ||
85 | struct GNUNET_DBUS_Service *service = (struct GNUNET_DBUS_Service *)data; | ||
86 | struct Watch *w = watch_create (watch); | ||
87 | |||
88 | if (dbus_watch_get_enabled (watch)) | ||
89 | watch_schedule (w); | ||
90 | |||
91 | struct WatchIter *wi = GNUNET_new (struct WatchIter); | ||
92 | wi->w = w; | ||
93 | GNUNET_CONTAINER_DLL_insert (service->watches_front, | ||
94 | service->watches_back, | ||
95 | wi); | ||
96 | return true; | ||
97 | }; | ||
98 | |||
99 | /* | ||
100 | * Called by DBus when it want to permanently disable and remove a watch | ||
101 | * | ||
102 | * @param watch The DBus watch, passed to us by DBus. | ||
103 | * @param data the GNUNET_DBUS_Service we passed to dbus_connection_set_watch_functions | ||
104 | */ | ||
105 | static void | ||
106 | watch_remove ( | ||
107 | DBusWatch *watch, | ||
108 | void *data) | ||
109 | { | ||
110 | struct GNUNET_DBUS_Service *service = (struct GNUNET_DBUS_Service *)data; | ||
111 | struct WatchIter *wi = watch_find (service->watches_front, watch); | ||
112 | |||
113 | if (NULL == wi) | ||
114 | { | ||
115 | LOG (GNUNET_ERROR_TYPE_ERROR, "Asked to remove watch that has not been added\n"); | ||
116 | GNUNET_abort_ (); | ||
117 | }; | ||
118 | |||
119 | struct Watch *w = wi->w; | ||
120 | watch_unschedule (w); | ||
121 | GNUNET_CONTAINER_DLL_remove (service->watches_front, | ||
122 | service->watches_back, | ||
123 | wi); | ||
124 | watch_unref (w); | ||
125 | GNUNET_free (wi); | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * Called by DBus when it wants to enable or disable a watch. | ||
130 | * Schedules or unschedules the scheduler to monitor this watch as appropriate. | ||
131 | * | ||
132 | * @param watch The DBus watch, passed to us by DBus. | ||
133 | * @param data the GNUNET_DBUS_Service we passed to dbus_connection_set_watch_functions | ||
134 | */ | ||
135 | static void | ||
136 | watch_toggle ( | ||
137 | DBusWatch *watch, | ||
138 | void *data) | ||
139 | { | ||
140 | struct GNUNET_DBUS_Service *service = (struct GNUNET_DBUS_Service *)data; | ||
141 | struct WatchIter *wi = watch_find (service->watches_front, watch); | ||
142 | |||
143 | if (NULL == wi) | ||
144 | { | ||
145 | LOG (GNUNET_ERROR_TYPE_ERROR, "Asked to toggle watch that has not been added\n"); | ||
146 | GNUNET_abort_ (); | ||
147 | }; | ||
148 | |||
149 | struct Watch *w = wi->w; | ||
150 | if (dbus_watch_get_enabled (watch)) | ||
151 | watch_unschedule (w); | ||
152 | else | ||
153 | watch_schedule (w); | ||
154 | }; | ||
155 | |||
156 | static dbus_bool_t | ||
157 | timeout_add ( | ||
158 | DBusTimeout *timeout, | ||
159 | void *data) | ||
160 | { | ||
161 | struct GNUNET_DBUS_Service *service = (struct GNUNET_DBUS_Service *)data; | ||
162 | struct Timeout *t = timeout_create (timeout); | ||
163 | |||
164 | if (dbus_timeout_get_enabled (timeout)) | ||
165 | timeout_schedule (t); | ||
166 | |||
167 | struct TimeoutIter *ti = GNUNET_new (struct TimeoutIter); | ||
168 | ti->t = t; | ||
169 | GNUNET_CONTAINER_DLL_insert (service->timeouts_front, | ||
170 | service->timeouts_back, | ||
171 | ti); | ||
172 | return true; | ||
173 | }; | ||
174 | |||
175 | static void | ||
176 | timeout_remove ( | ||
177 | DBusTimeout *timeout, | ||
178 | void *data) | ||
179 | { | ||
180 | struct GNUNET_DBUS_Service *service = (struct GNUNET_DBUS_Service *)data; | ||
181 | struct TimeoutIter *ti = timeout_find (service->timeouts_front, timeout); | ||
182 | |||
183 | if (NULL == ti) | ||
184 | { | ||
185 | LOG (GNUNET_ERROR_TYPE_WARNING, "Asked to remove timeout that has not been added\n"); | ||
186 | return; | ||
187 | }; | ||
188 | |||
189 | struct Timeout *t = ti->t; | ||
190 | timeout_unschedule (t); | ||
191 | GNUNET_CONTAINER_DLL_remove (service->timeouts_front, | ||
192 | service->timeouts_back, | ||
193 | ti); | ||
194 | timeout_unref (t); | ||
195 | GNUNET_free (ti); | ||
196 | }; | ||
197 | |||
198 | static void | ||
199 | timeout_toggle ( | ||
200 | DBusTimeout *timeout, | ||
201 | void *data) | ||
202 | { | ||
203 | struct GNUNET_DBUS_Service *service = (struct GNUNET_DBUS_Service *)data; | ||
204 | struct TimeoutIter *ti = timeout_find (service->timeouts_front, timeout); | ||
205 | |||
206 | if (NULL == ti) | ||
207 | { | ||
208 | LOG (GNUNET_ERROR_TYPE_WARNING, "asked to toggle timeout that has not been added\n"); | ||
209 | return; | ||
210 | }; | ||
211 | |||
212 | struct Timeout *t = ti->t; | ||
213 | if (dbus_timeout_get_enabled (timeout)) | ||
214 | timeout_unschedule (t); | ||
215 | else | ||
216 | timeout_schedule (t); | ||
217 | }; | ||
218 | |||
219 | |||
220 | static void | ||
221 | dispatch ( | ||
222 | void *cls, | ||
223 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
224 | |||
225 | |||
226 | static void | ||
227 | handle_dispatch ( | ||
228 | DBusConnection *dbus_connection, | ||
229 | DBusDispatchStatus status) | ||
230 | { | ||
231 | switch (status) | ||
232 | { | ||
233 | case DBUS_DISPATCH_DATA_REMAINS: | ||
234 | GNUNET_SCHEDULER_add_now (dispatch, | ||
235 | dbus_connection); | ||
236 | break; | ||
237 | case DBUS_DISPATCH_COMPLETE: | ||
238 | break; | ||
239 | case DBUS_DISPATCH_NEED_MEMORY: | ||
240 | LOG (GNUNET_ERROR_TYPE_ERROR, "Out of memory!\n"); | ||
241 | GNUNET_abort_ (); | ||
242 | break; | ||
243 | default: | ||
244 | LOG (GNUNET_ERROR_TYPE_ERROR, "Unrecognized dispatch status\n"); | ||
245 | break; | ||
246 | }; | ||
247 | }; | ||
248 | |||
249 | |||
250 | static void | ||
251 | dispatch ( | ||
252 | void *cls, | ||
253 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
254 | { | ||
255 | struct DBusConnection *dbus_connection = (struct DBusConnection *)cls; | ||
256 | dbus_connection_dispatch (dbus_connection); | ||
257 | handle_dispatch (dbus_connection, dbus_connection_get_dispatch_status (dbus_connection)); | ||
258 | }; | ||
259 | |||
260 | |||
261 | static void | ||
262 | dispatch_status_changed ( | ||
263 | DBusConnection *dbus_connection, | ||
264 | DBusDispatchStatus new_status, | ||
265 | void *data) | ||
266 | { | ||
267 | (void)data; | ||
268 | handle_dispatch (dbus_connection, new_status); | ||
269 | }; | ||
270 | |||
271 | /* | ||
272 | * Called whenever a message arrives from DBus | ||
273 | * | ||
274 | * @param conn The connection it arrived on. | ||
275 | * @param message The message | ||
276 | * @param cls The closure passed to dbus_connection_try_register_object_path | ||
277 | * in our case this is the GNUNET_DBUS_Object that the message was | ||
278 | * sent to. | ||
279 | * | ||
280 | * @return DBUS_HANDLER_RESULT_NEED_MEMORY if anything failed due to lack of | ||
281 | * memory. | ||
282 | * DBUS_HANDLER_RESULT_HANDLED if any method returned a reply. | ||
283 | * DBUS_HANDLER_RESULT_NOT_YET_HANDLED otherwise. | ||
284 | */ | ||
285 | DBusHandlerResult | ||
286 | handle_object_message ( | ||
287 | DBusConnection *connection, | ||
288 | DBusMessage *dbus_message, | ||
289 | void *cls) | ||
290 | { | ||
291 | //struct GNUNET_DBUS_Object *object = (struct GNUNET_DBUS_Object *)cls; | ||
292 | (void)cls; | ||
293 | |||
294 | const char *object_path = dbus_message_get_path (dbus_message); | ||
295 | const char *type_string = dbus_message_type_to_string (dbus_message_get_type (dbus_message)); | ||
296 | const char *interface_name = dbus_message_get_interface (dbus_message); | ||
297 | const char *member_name = dbus_message_get_member (dbus_message); | ||
298 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Recieved DBus message for %s\n", object_path); | ||
299 | LOG (GNUNET_ERROR_TYPE_DEBUG, " type == %s\n", type_string ? type_string : "(none)"); | ||
300 | LOG (GNUNET_ERROR_TYPE_DEBUG, " interface == %s\n", interface_name ? interface_name : "(none)"); | ||
301 | LOG (GNUNET_ERROR_TYPE_DEBUG, " member == %s\n", member_name ? member_name : "(none)"); | ||
302 | |||
303 | struct GNUNET_DBUS_Service *service = dbus_connection_get_data (connection, service_slot_id ()); | ||
304 | |||
305 | const char *unique_name = dbus_message_get_sender (dbus_message); | ||
306 | struct GNUNET_DBUS_ClientIterator *client_it = service->clients_front; | ||
307 | struct GNUNET_DBUS_Client *client = NULL; | ||
308 | for (; client_it; client_it = client_it->next) | ||
309 | { | ||
310 | client = client_it->client; | ||
311 | const char *this_unique_name = GNUNET_DBUS_client_get_unique_name (client); | ||
312 | if (! strcmp (unique_name, this_unique_name)) | ||
313 | break; | ||
314 | }; | ||
315 | if (! client_it) | ||
316 | { | ||
317 | client = GNUNET_DBUS_client_create (unique_name); | ||
318 | client_it = GNUNET_new (struct GNUNET_DBUS_ClientIterator); | ||
319 | client_it->client = client; | ||
320 | GNUNET_CONTAINER_DLL_insert (service->clients_front, | ||
321 | service->clients_back, | ||
322 | client_it); | ||
323 | if (service->client_connects) | ||
324 | service->client_connects (service, client); | ||
325 | /* | ||
326 | |||
327 | ** TODO ** | ||
328 | |||
329 | detect when a client is no longer on the bus and | ||
330 | destroy the client object. At the moment this will slowly | ||
331 | leak memory as clients come and go. | ||
332 | |||
333 | */ | ||
334 | }; | ||
335 | |||
336 | /* | ||
337 | * TODO: | ||
338 | * | ||
339 | * The code below could be more efficient. Avoid the allocation with | ||
340 | * dbus_message_get_path_decomposed and use tries to do | ||
341 | * object/method/interface lookups. | ||
342 | */ | ||
343 | char **path_decomposed = NULL; | ||
344 | dbus_bool_t succ = dbus_message_get_path_decomposed (dbus_message, &path_decomposed); | ||
345 | if (! succ) | ||
346 | { | ||
347 | LOG (GNUNET_ERROR_TYPE_ERROR, "Ran out of memory in dbus_message_get_path_decomposed.\n"); | ||
348 | GNUNET_abort_ (); | ||
349 | }; | ||
350 | |||
351 | struct GNUNET_DBUS_Object *object = service->root_object; | ||
352 | char **path_element = path_decomposed; | ||
353 | while (*path_element) | ||
354 | { | ||
355 | const struct GNUNET_DBUS_ObjectIterator *start = GNUNET_DBUS_object_iterate_subobjects (object); | ||
356 | const struct GNUNET_DBUS_ObjectIterator *found = GNUNET_DBUS_object_find (start, *path_element); | ||
357 | if (! found) | ||
358 | { | ||
359 | const char *object_name = GNUNET_DBUS_object_get_name (object); | ||
360 | LOG (GNUNET_ERROR_TYPE_DEBUG, "No such object \"%s\" under \"%s\"\n", *path_element, object_name[0] ? object_name : "(root object)"); | ||
361 | dbus_free_string_array (path_decomposed); | ||
362 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
363 | }; | ||
364 | |||
365 | object = found->object; | ||
366 | path_element++; | ||
367 | }; | ||
368 | dbus_free_string_array (path_decomposed); | ||
369 | |||
370 | if (! member_name) | ||
371 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
372 | |||
373 | if (! interface_name) | ||
374 | interface_name = service->well_known_name; | ||
375 | |||
376 | int dbus_message_type = dbus_message_get_type (dbus_message); | ||
377 | if (dbus_message_type != DBUS_MESSAGE_TYPE_METHOD_CALL) | ||
378 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
379 | |||
380 | const struct GNUNET_DBUS_InterfaceIterator *int_it = \ | ||
381 | GNUNET_DBUS_interface_find ( \ | ||
382 | GNUNET_DBUS_object_iterate_interfaces (object), | ||
383 | interface_name); | ||
384 | if (! int_it) | ||
385 | { | ||
386 | LOG (GNUNET_ERROR_TYPE_DEBUG, "No such interface: %s\n", interface_name); | ||
387 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
388 | }; | ||
389 | struct GNUNET_DBUS_Interface *interface = int_it->interface; | ||
390 | |||
391 | const struct GNUNET_DBUS_MethodIterator *meth_it = \ | ||
392 | GNUNET_DBUS_method_find ( \ | ||
393 | GNUNET_DBUS_interface_iterate_methods (interface), | ||
394 | member_name); | ||
395 | if (! meth_it) | ||
396 | { | ||
397 | LOG (GNUNET_ERROR_TYPE_DEBUG, "No such method: %s\n", member_name); | ||
398 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
399 | }; | ||
400 | struct GNUNET_DBUS_Method *method = meth_it->method; | ||
401 | |||
402 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Found method.\n"); | ||
403 | |||
404 | struct GNUNET_DBUS_MethodContext *mc = GNUNET_DBUS_method_context_create ( | ||
405 | client, | ||
406 | service, | ||
407 | object, | ||
408 | interface, | ||
409 | method, | ||
410 | dbus_message | ||
411 | ); | ||
412 | GNUNET_DBUS_method_call (method, mc); | ||
413 | GNUNET_DBUS_method_context_unref (mc); | ||
414 | return DBUS_HANDLER_RESULT_HANDLED; | ||
415 | }; | ||
416 | |||
417 | struct GNUNET_DBUS_Service * | ||
418 | GNUNET_DBUS_service_create ( | ||
419 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
420 | const char *name) | ||
421 | { | ||
422 | struct GNUNET_DBUS_Service *service = GNUNET_new (struct GNUNET_DBUS_Service); | ||
423 | service->cfg = cfg; | ||
424 | service->gnunet_name = GNUNET_strdup (name); | ||
425 | service->watches_front = NULL; | ||
426 | service->watches_back = NULL; | ||
427 | service->timeouts_front = NULL; | ||
428 | service->timeouts_back = NULL; | ||
429 | service->client_connects = NULL; | ||
430 | service->client_disconnects = NULL; | ||
431 | service->ref_count = 1; | ||
432 | |||
433 | DBusError err; | ||
434 | dbus_error_init(&err); | ||
435 | |||
436 | service->root_object = GNUNET_DBUS_object_create ("", NULL); | ||
437 | if (! service->root_object) | ||
438 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create root object for service.\n"); | ||
439 | else | ||
440 | { | ||
441 | service->dbus_connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &err); | ||
442 | if (! service->dbus_connection) | ||
443 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to connect to dbus system bus (%s)\n", dbus_error_is_set (&err) ? err.message : "dbus_bus_get_private returned NULL"); | ||
444 | else | ||
445 | { | ||
446 | dbus_connection_set_exit_on_disconnect (service->dbus_connection, | ||
447 | false); | ||
448 | dbus_bool_t succ = dbus_connection_set_data (service->dbus_connection, | ||
449 | service_slot_id (), | ||
450 | service, | ||
451 | NULL); | ||
452 | if (! succ) | ||
453 | { | ||
454 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_connection_set_data returned false. Out of memory.\n"); | ||
455 | GNUNET_abort_ (); | ||
456 | }; | ||
457 | |||
458 | succ = dbus_connection_set_watch_functions (service->dbus_connection, watch_add, watch_remove, watch_toggle, service, NULL); | ||
459 | if(! succ) | ||
460 | { | ||
461 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_connection_set_watch_functions returned false. Out of memory.\n"); | ||
462 | GNUNET_abort_ (); | ||
463 | }; | ||
464 | |||
465 | dbus_connection_set_dispatch_status_function (service->dbus_connection, dispatch_status_changed, service, NULL); | ||
466 | handle_dispatch (service->dbus_connection, dbus_connection_get_dispatch_status (service->dbus_connection)); | ||
467 | |||
468 | succ = dbus_connection_set_timeout_functions (service->dbus_connection, timeout_add, timeout_remove, timeout_toggle, service, NULL); | ||
469 | if (! succ) | ||
470 | { | ||
471 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_connection_set_timeout_functions returned false. Out of memory.\n"); | ||
472 | GNUNET_abort_ (); | ||
473 | }; | ||
474 | |||
475 | DBusObjectPathVTable vtable; | ||
476 | vtable.message_function = handle_object_message; | ||
477 | vtable.unregister_function = NULL; | ||
478 | succ = dbus_connection_try_register_fallback (service->dbus_connection, "/", &vtable, service, &err); | ||
479 | if (dbus_error_is_set (&err) || ! succ) | ||
480 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_connection_try_register_fallback failed when registering root object.\n"); | ||
481 | else | ||
482 | { | ||
483 | service->well_known_name = NULL; | ||
484 | GNUNET_asprintf (&service->well_known_name, "gnu.gnunet.%s", name); | ||
485 | int request_result = dbus_bus_request_name (service->dbus_connection, service->well_known_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); | ||
486 | if (dbus_error_is_set (&err)) | ||
487 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to request the bus name (%s)\n", err.message); | ||
488 | else | ||
489 | { | ||
490 | switch(request_result) | ||
491 | { | ||
492 | case DBUS_REQUEST_NAME_REPLY_EXISTS: | ||
493 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to request the bus name \"%s\"; name is already taken.\n", service->well_known_name); | ||
494 | break; | ||
495 | default: | ||
496 | LOG (GNUNET_ERROR_TYPE_ERROR, "Unable to interpret result of dbus_request_name (%d)\n", request_result); | ||
497 | break; | ||
498 | case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: | ||
499 | |||
500 | /* Success! */ | ||
501 | return service; | ||
502 | |||
503 | } | ||
504 | } | ||
505 | dbus_connection_unregister_object_path (service->dbus_connection, "/"); | ||
506 | } | ||
507 | dbus_connection_close (service->dbus_connection); | ||
508 | dbus_connection_unref (service->dbus_connection); | ||
509 | } | ||
510 | GNUNET_DBUS_object_unref (service->root_object); | ||
511 | } | ||
512 | GNUNET_free (service->well_known_name); | ||
513 | GNUNET_free (service->gnunet_name); | ||
514 | GNUNET_free (service); | ||
515 | LOG (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DBUS_service create failed.\n"); | ||
516 | return NULL; | ||
517 | }; | ||
518 | |||
519 | void | ||
520 | GNUNET_DBUS_service_ref ( | ||
521 | struct GNUNET_DBUS_Service *service) | ||
522 | { | ||
523 | service->ref_count++; | ||
524 | } | ||
525 | |||
526 | void | ||
527 | GNUNET_DBUS_service_unref ( | ||
528 | struct GNUNET_DBUS_Service *service) | ||
529 | { | ||
530 | if (service->ref_count == 0) | ||
531 | { | ||
532 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unref service with ref count 0\n"); | ||
533 | LOG (GNUNET_ERROR_TYPE_ERROR, " well_known_name == %s\n", service->well_known_name); | ||
534 | GNUNET_abort_ (); | ||
535 | } | ||
536 | |||
537 | if (0 == --(service->ref_count)) | ||
538 | { | ||
539 | GNUNET_DBUS_object_unref (service->root_object); | ||
540 | |||
541 | GNUNET_free (service->well_known_name); | ||
542 | GNUNET_free (service->gnunet_name); | ||
543 | |||
544 | struct WatchIter *wi = service->watches_front; | ||
545 | while (wi) | ||
546 | { | ||
547 | struct WatchIter *next = wi->next; | ||
548 | watch_unref (wi->w); | ||
549 | GNUNET_free (wi); | ||
550 | wi = next; | ||
551 | } | ||
552 | |||
553 | struct TimeoutIter *ti = service->timeouts_front; | ||
554 | while (ti) | ||
555 | { | ||
556 | struct TimeoutIter *next = ti->next; | ||
557 | timeout_unref (ti->t); | ||
558 | GNUNET_free (ti); | ||
559 | ti = next; | ||
560 | } | ||
561 | |||
562 | struct GNUNET_DBUS_ClientIterator *ci = service->clients_front; | ||
563 | while (ci) | ||
564 | { | ||
565 | struct GNUNET_DBUS_ClientIterator *next = ci->next; | ||
566 | GNUNET_DBUS_client_unref (ci->client); | ||
567 | GNUNET_free (ci); | ||
568 | ci = next; | ||
569 | } | ||
570 | |||
571 | GNUNET_free (service); | ||
572 | } | ||
573 | }; | ||
574 | |||
575 | const struct GNUNET_CONFIGURATION_Handle * | ||
576 | GNUNET_DBUS_service_get_config ( | ||
577 | struct GNUNET_DBUS_Service *service) | ||
578 | { | ||
579 | return service->cfg; | ||
580 | }; | ||
581 | |||
582 | #if 0 | ||
583 | int | ||
584 | GNUNET_DBUS_service_add_object ( | ||
585 | struct GNUNET_DBUS_Service *service, | ||
586 | struct GNUNET_DBUS_Object *object) | ||
587 | { | ||
588 | DBusError err; | ||
589 | dbus_error_init(&err); | ||
590 | |||
591 | const char *path = GNUNET_DBUS_object_get_path (object); | ||
592 | |||
593 | DBusObjectPathVTable vtable; | ||
594 | vtable.message_function = handle_object_message; | ||
595 | vtable.unregister_function = NULL; | ||
596 | dbus_bool_t succ = dbus_connection_try_register_object_path ( | ||
597 | service->dbus_connection, | ||
598 | path, | ||
599 | &vtable, | ||
600 | object, | ||
601 | &err); | ||
602 | if (dbus_error_is_set (&err)) | ||
603 | { | ||
604 | LOG ( | ||
605 | GNUNET_ERROR_TYPE_ERROR, | ||
606 | "dbus_connection_try_register failed to register path \"%s\": %s\n", | ||
607 | path, | ||
608 | err.message); | ||
609 | return GNUNET_SYSERR; | ||
610 | }; | ||
611 | if (! succ) | ||
612 | { | ||
613 | LOG ( | ||
614 | GNUNET_ERROR_TYPE_ERROR, | ||
615 | "dbus_connection_try_register returned false when registering path \"%s\"\n", | ||
616 | path); | ||
617 | return GNUNET_SYSERR; | ||
618 | }; | ||
619 | |||
620 | struct GNUNET_DBUS_ObjectIterator *object_it = GNUNET_new (struct GNUNET_DBUS_ObjectIterator); | ||
621 | object_it->object = object; | ||
622 | GNUNET_DBUS_object_ref (object); | ||
623 | GNUNET_CONTAINER_DLL_insert (service->objects_front, | ||
624 | service->objects_back, | ||
625 | object_it); | ||
626 | |||
627 | return GNUNET_OK; | ||
628 | }; | ||
629 | |||
630 | void | ||
631 | GNUNET_DBUS_service_remove_object ( | ||
632 | struct GNUNET_DBUS_Service *service, | ||
633 | struct GNUNET_DBUS_Object *object) | ||
634 | { | ||
635 | struct GNUNET_DBUS_ObjectIterator *obj_it; | ||
636 | for (obj_it = service->objects_front; obj_it; obj_it = obj_it->next) | ||
637 | { | ||
638 | if (obj_it->object == object) | ||
639 | break; | ||
640 | }; | ||
641 | |||
642 | if (! obj_it) | ||
643 | { | ||
644 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to remove object that has not been added.\n"); | ||
645 | GNUNET_abort_ (); | ||
646 | }; | ||
647 | |||
648 | GNUNET_CONTAINER_DLL_remove ( | ||
649 | service->objects_front, | ||
650 | service->objects_back, | ||
651 | obj_it); | ||
652 | |||
653 | GNUNET_free (obj_it); | ||
654 | GNUNET_DBUS_object_unref (object); | ||
655 | } | ||
656 | #endif | ||
657 | |||
658 | void | ||
659 | GNUNET_DBUS_service_send ( | ||
660 | struct GNUNET_DBUS_Service *service, | ||
661 | DBusMessage *dbus_message) | ||
662 | { | ||
663 | dbus_bool_t succ = dbus_connection_send (service->dbus_connection, dbus_message, NULL); | ||
664 | if (! succ) | ||
665 | { | ||
666 | LOG (GNUNET_ERROR_TYPE_ERROR, "dbus_connection_send failed. Out of memory.\n"); | ||
667 | GNUNET_abort_ (); | ||
668 | }; | ||
669 | }; | ||
670 | |||
671 | void | ||
672 | GNUNET_DBUS_service_set_client_handlers ( | ||
673 | struct GNUNET_DBUS_Service *service, | ||
674 | GNUNET_DBUS_ClientConnectsHandler client_connects, | ||
675 | GNUNET_DBUS_ClientDisconnectsHandler client_disconnects) | ||
676 | { | ||
677 | service->client_connects = client_connects; | ||
678 | service->client_disconnects = client_disconnects; | ||
679 | }; | ||
680 | |||
681 | struct GNUNET_DBUS_Object * | ||
682 | GNUNET_DBUS_service_get_root_object ( | ||
683 | struct GNUNET_DBUS_Service *service) | ||
684 | { | ||
685 | return service->root_object; | ||
686 | } | ||
diff --git a/src/lib/common/gnunet_dbus_lib_signal.c b/src/lib/common/gnunet_dbus_lib_signal.c new file mode 100644 index 0000000..0597200 --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_signal.c | |||
@@ -0,0 +1,126 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_container_lib.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib.h" | ||
8 | |||
9 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-signal", __VA_ARGS__) | ||
10 | |||
11 | struct GNUNET_DBUS_Signal | ||
12 | { | ||
13 | struct GNUNET_DBUS_ArgIterator *args_front; | ||
14 | struct GNUNET_DBUS_ArgIterator *args_back; | ||
15 | |||
16 | struct GNUNET_DBUS_Interface *owner; | ||
17 | |||
18 | char *name; | ||
19 | |||
20 | unsigned ref_count; | ||
21 | }; | ||
22 | |||
23 | struct GNUNET_DBUS_Signal * | ||
24 | GNUNET_DBUS_signal_create ( | ||
25 | const char *name) | ||
26 | { | ||
27 | struct GNUNET_DBUS_Signal *ret = GNUNET_new (struct GNUNET_DBUS_Signal); | ||
28 | ret->args_front = NULL; | ||
29 | ret->args_back = NULL; | ||
30 | ret->owner = NULL; | ||
31 | ret->name = strdup (name); | ||
32 | ret->ref_count = 1; | ||
33 | |||
34 | return ret; | ||
35 | } | ||
36 | |||
37 | void | ||
38 | GNUNET_DBUS_signal_ref ( | ||
39 | struct GNUNET_DBUS_Signal *signal) | ||
40 | { | ||
41 | signal->ref_count++; | ||
42 | } | ||
43 | |||
44 | void | ||
45 | GNUNET_DBUS_signal_unref ( | ||
46 | struct GNUNET_DBUS_Signal *signal) | ||
47 | { | ||
48 | if (signal->ref_count == 0) | ||
49 | { | ||
50 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference signal with ref count 0.\n"); | ||
51 | GNUNET_abort_ (); | ||
52 | } | ||
53 | if (0 == --(signal->ref_count)) | ||
54 | { | ||
55 | struct GNUNET_DBUS_ArgIterator *arg_it = signal->args_front; | ||
56 | while (arg_it) | ||
57 | { | ||
58 | struct GNUNET_DBUS_ArgIterator *next = arg_it->next; | ||
59 | GNUNET_DBUS_arg_unref (arg_it->arg); | ||
60 | GNUNET_free (arg_it); | ||
61 | arg_it = next; | ||
62 | } | ||
63 | |||
64 | GNUNET_free (signal->name); | ||
65 | GNUNET_free (signal); | ||
66 | } | ||
67 | }; | ||
68 | |||
69 | void | ||
70 | GNUNET_DBUS_signal_add_arg ( | ||
71 | struct GNUNET_DBUS_Signal *signal, | ||
72 | const char *name, | ||
73 | const char *signature) | ||
74 | { | ||
75 | struct GNUNET_DBUS_Arg *arg = GNUNET_DBUS_arg_create (name, signature); | ||
76 | struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_new (struct GNUNET_DBUS_ArgIterator); | ||
77 | arg_it->arg = arg; | ||
78 | GNUNET_CONTAINER_DLL_insert_tail (signal->args_front, | ||
79 | signal->args_back, | ||
80 | arg_it); | ||
81 | }; | ||
82 | |||
83 | const char * | ||
84 | GNUNET_DBUS_signal_get_name ( | ||
85 | const struct GNUNET_DBUS_Signal *signal) | ||
86 | { | ||
87 | return signal->name; | ||
88 | } | ||
89 | |||
90 | const struct GNUNET_DBUS_ArgIterator * | ||
91 | GNUNET_DBUS_signal_iterate_args ( | ||
92 | const struct GNUNET_DBUS_Signal *signal) | ||
93 | { | ||
94 | return signal->args_front; | ||
95 | } | ||
96 | |||
97 | DBusMessage * | ||
98 | GNUNET_DBUS_signal_spawn ( | ||
99 | const struct GNUNET_DBUS_Signal *signal, | ||
100 | const struct GNUNET_DBUS_ObjectPath *path, | ||
101 | const struct GNUNET_DBUS_Interface *interface, | ||
102 | bool pretty) | ||
103 | { | ||
104 | char *path_str = GNUNET_DBUS_object_path_to_string (path); | ||
105 | DBusMessage *ret = dbus_message_new_signal ( | ||
106 | path_str, | ||
107 | GNUNET_DBUS_interface_get_name (interface), | ||
108 | signal->name); | ||
109 | GNUNET_free (path_str); | ||
110 | GNUNET_DBUS_message_set_pretty (ret, pretty); | ||
111 | return ret; | ||
112 | }; | ||
113 | |||
114 | DBusMessage * | ||
115 | GNUNET_DBUS_signal_spawn_unicast ( | ||
116 | const struct GNUNET_DBUS_Signal *signal, | ||
117 | const struct GNUNET_DBUS_ObjectPath *path, | ||
118 | const struct GNUNET_DBUS_Interface *interface, | ||
119 | const struct GNUNET_DBUS_Client *client, | ||
120 | bool pretty) | ||
121 | { | ||
122 | DBusMessage *ret = GNUNET_DBUS_signal_spawn (signal, path, interface, pretty); | ||
123 | dbus_message_set_destination (ret, GNUNET_DBUS_client_get_unique_name (client)); | ||
124 | return ret; | ||
125 | } | ||
126 | |||
diff --git a/src/lib/common/gnunet_dbus_lib_signature.c b/src/lib/common/gnunet_dbus_lib_signature.c new file mode 100644 index 0000000..73832fb --- /dev/null +++ b/src/lib/common/gnunet_dbus_lib_signature.c | |||
@@ -0,0 +1,60 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_dbus_lib.h" | ||
4 | |||
5 | const char * | ||
6 | GNUNET_DBUS_signature_typecode_to_string ( | ||
7 | int typecode) | ||
8 | { | ||
9 | switch (typecode) | ||
10 | { | ||
11 | case DBUS_TYPE_INVALID: | ||
12 | return "nothing"; | ||
13 | case DBUS_TYPE_BOOLEAN: | ||
14 | return "boolean"; | ||
15 | case DBUS_TYPE_BYTE: | ||
16 | return "byte"; | ||
17 | case DBUS_TYPE_INT16: | ||
18 | return "int16"; | ||
19 | case DBUS_TYPE_UINT16: | ||
20 | return "uint16"; | ||
21 | case DBUS_TYPE_INT32: | ||
22 | return "int32"; | ||
23 | case DBUS_TYPE_UINT32: | ||
24 | return "uint32"; | ||
25 | case DBUS_TYPE_INT64: | ||
26 | return "int64"; | ||
27 | case DBUS_TYPE_UINT64: | ||
28 | return "uint64"; | ||
29 | case DBUS_TYPE_DOUBLE: | ||
30 | return "double"; | ||
31 | case DBUS_TYPE_STRING: | ||
32 | return "string"; | ||
33 | case DBUS_TYPE_OBJECT_PATH: | ||
34 | return "object_path"; | ||
35 | case DBUS_TYPE_SIGNATURE: | ||
36 | return "signature"; | ||
37 | case DBUS_TYPE_STRUCT: | ||
38 | return "struct"; | ||
39 | case DBUS_TYPE_DICT_ENTRY: | ||
40 | return "dict_entry"; | ||
41 | case DBUS_TYPE_ARRAY: | ||
42 | return "array"; | ||
43 | case DBUS_TYPE_VARIANT: | ||
44 | return "variant"; | ||
45 | case DBUS_STRUCT_BEGIN_CHAR: | ||
46 | return "begin_struct"; | ||
47 | case DBUS_STRUCT_END_CHAR: | ||
48 | return "end_struct"; | ||
49 | case DBUS_DICT_ENTRY_BEGIN_CHAR: | ||
50 | return "begin_dict_entry"; | ||
51 | case DBUS_DICT_ENTRY_END_CHAR: | ||
52 | return "end_dict_entry"; | ||
53 | case DBUS_TYPE_UNIX_FD: | ||
54 | return "unix_fd"; | ||
55 | default: | ||
56 | return "unknown"; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | |||
diff --git a/src/lib/common/timeout.c b/src/lib/common/timeout.c new file mode 100644 index 0000000..b12780b --- /dev/null +++ b/src/lib/common/timeout.c | |||
@@ -0,0 +1,131 @@ | |||
1 | #include "timeout.h" | ||
2 | |||
3 | #include <stdbool.h> | ||
4 | |||
5 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-timeout", __VA_ARGS__) | ||
6 | |||
7 | struct Timeout | ||
8 | { | ||
9 | /* doubly-linked list */ | ||
10 | struct Timeout *next; | ||
11 | struct Timeout *prev; | ||
12 | |||
13 | DBusTimeout *timeout; | ||
14 | |||
15 | bool scheduled; | ||
16 | |||
17 | struct GNUNET_SCHEDULER_Task *task; | ||
18 | |||
19 | unsigned ref_count; | ||
20 | }; | ||
21 | |||
22 | struct Timeout * | ||
23 | timeout_create ( | ||
24 | DBusTimeout *timeout) | ||
25 | { | ||
26 | struct Timeout *t = GNUNET_new (struct Timeout); | ||
27 | |||
28 | t->timeout = timeout; | ||
29 | t->scheduled = false; | ||
30 | t->ref_count = 1; | ||
31 | |||
32 | return t; | ||
33 | } | ||
34 | |||
35 | void | ||
36 | timeout_ref ( | ||
37 | struct Timeout *t) | ||
38 | { | ||
39 | t->ref_count++; | ||
40 | } | ||
41 | |||
42 | void | ||
43 | timeout_unref ( | ||
44 | struct Timeout *t) | ||
45 | { | ||
46 | if (0 == t->ref_count) | ||
47 | { | ||
48 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unref timeout with ref_count == 0\n"); | ||
49 | GNUNET_abort_ (); | ||
50 | }; | ||
51 | |||
52 | if (0 == --t->ref_count) | ||
53 | { | ||
54 | GNUNET_free (t); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static void | ||
59 | handle_timeout ( | ||
60 | void *cls, | ||
61 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
62 | { | ||
63 | struct Timeout *t = (struct Timeout *)cls; | ||
64 | |||
65 | t->scheduled = false; | ||
66 | |||
67 | if (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) | ||
68 | dbus_timeout_handle (t->timeout); | ||
69 | |||
70 | if (t->ref_count > 1 && ! (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
71 | timeout_schedule (t); | ||
72 | timeout_unref (t); | ||
73 | }; | ||
74 | |||
75 | void | ||
76 | timeout_schedule ( | ||
77 | struct Timeout *t) | ||
78 | { | ||
79 | if (! dbus_timeout_get_enabled (t->timeout)) | ||
80 | { | ||
81 | LOG (GNUNET_ERROR_TYPE_WARNING, "Tried to schedule timeout that is disabled!\n"); | ||
82 | return; | ||
83 | }; | ||
84 | |||
85 | if (t->scheduled) | ||
86 | return; | ||
87 | |||
88 | int interval = dbus_timeout_get_interval (t->timeout); | ||
89 | struct GNUNET_TIME_Relative delay; | ||
90 | delay.rel_value_us = interval * 1000; | ||
91 | t->task = GNUNET_SCHEDULER_add_delayed ( | ||
92 | delay, | ||
93 | handle_timeout, | ||
94 | t); | ||
95 | t->scheduled = true; | ||
96 | timeout_ref (t); | ||
97 | } | ||
98 | |||
99 | void | ||
100 | do_timeout_unschedule ( | ||
101 | void *cls, | ||
102 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
103 | { | ||
104 | (void)tc; | ||
105 | struct Timeout *t = (struct Timeout *)cls; | ||
106 | |||
107 | if (! t->scheduled) | ||
108 | return; | ||
109 | |||
110 | void *ret = GNUNET_SCHEDULER_cancel (t->task); | ||
111 | if ((struct Timeout *)ret != t) | ||
112 | LOG (GNUNET_ERROR_TYPE_WARNING, "Weird result unscheduling task. t == %p, GNUNET_SCHEDULER_cancel returned %p\n", t, ret); | ||
113 | |||
114 | timeout_unref (t); | ||
115 | } | ||
116 | |||
117 | void | ||
118 | timeout_unschedule ( | ||
119 | struct Timeout *t) | ||
120 | { | ||
121 | GNUNET_SCHEDULER_add_now (do_timeout_unschedule, t); | ||
122 | } | ||
123 | |||
124 | struct TimeoutIter * | ||
125 | timeout_find (struct TimeoutIter *ti, DBusTimeout *timeout) | ||
126 | { | ||
127 | while (ti && ti->t->timeout != timeout) | ||
128 | ti = ti->next; | ||
129 | return ti; | ||
130 | } | ||
131 | |||
diff --git a/src/lib/common/timeout.h b/src/lib/common/timeout.h new file mode 100644 index 0000000..5230057 --- /dev/null +++ b/src/lib/common/timeout.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #ifndef TIMEOUT_H | ||
2 | #define TIMEOUT_H | ||
3 | |||
4 | #include <dbus/dbus.h> | ||
5 | |||
6 | #include <gnunet/platform.h> | ||
7 | #include <gnunet/gnunet_common.h> | ||
8 | #include <gnunet/gnunet_scheduler_lib.h> | ||
9 | |||
10 | struct Timeout; | ||
11 | |||
12 | struct TimeoutIter | ||
13 | { | ||
14 | struct TimeoutIter *next; | ||
15 | struct TimeoutIter *prev; | ||
16 | |||
17 | struct Timeout *t; | ||
18 | }; | ||
19 | |||
20 | struct Timeout *timeout_create (DBusTimeout *timeout); | ||
21 | void timeout_ref (struct Timeout *t); | ||
22 | void timeout_unref (struct Timeout *t); | ||
23 | |||
24 | void timeout_schedule (struct Timeout *t); | ||
25 | void timeout_unschedule (struct Timeout *t); | ||
26 | void do_timeout_unschedule (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
27 | |||
28 | struct TimeoutIter *timeout_find (struct TimeoutIter *, DBusTimeout *timeout); | ||
29 | |||
30 | #endif | ||
31 | |||
diff --git a/src/lib/common/watch.c b/src/lib/common/watch.c new file mode 100644 index 0000000..e6b5317 --- /dev/null +++ b/src/lib/common/watch.c | |||
@@ -0,0 +1,235 @@ | |||
1 | #include "watch.h" | ||
2 | |||
3 | #include <stdbool.h> | ||
4 | |||
5 | #define LOG(kind, ...) GNUNET_log_from (kind, "dbus-watch", __VA_ARGS__) | ||
6 | |||
7 | /* | ||
8 | * Wraps a file descriptor that needs to be watched | ||
9 | * for activity with select() | ||
10 | */ | ||
11 | struct Watch | ||
12 | { | ||
13 | /* | ||
14 | * DBus watch data. Contains the actual file descritor wrapped by libdbus | ||
15 | */ | ||
16 | DBusWatch *watch; | ||
17 | |||
18 | /* | ||
19 | * Have we asked the scheduler to watch this? | ||
20 | * Will be false if the associated task has not been | ||
21 | * re-scheduled yet after execution or because dbus has asked | ||
22 | * us to disable this watch. | ||
23 | */ | ||
24 | bool scheduled; | ||
25 | |||
26 | /* | ||
27 | * The task that is watching our file descriptor. | ||
28 | * Only valid if scheduled is true. | ||
29 | */ | ||
30 | struct GNUNET_SCHEDULER_Task *task; | ||
31 | |||
32 | struct GNUNET_NETWORK_Handle *net_handle; | ||
33 | struct GNUNET_DISK_FileHandle *file_handle; | ||
34 | |||
35 | unsigned ref_count; | ||
36 | }; | ||
37 | |||
38 | struct Watch * | ||
39 | watch_create ( | ||
40 | DBusWatch *watch) | ||
41 | { | ||
42 | struct Watch *w = GNUNET_new (struct Watch); | ||
43 | |||
44 | w->watch = watch; | ||
45 | w->scheduled = false; | ||
46 | w->net_handle = NULL; | ||
47 | w->file_handle = NULL; | ||
48 | w->ref_count = 1; | ||
49 | |||
50 | SOCKTYPE sock = dbus_watch_get_socket (watch); | ||
51 | if (-1 != sock) | ||
52 | { | ||
53 | w->net_handle = GNUNET_NETWORK_socket_box_native (sock); | ||
54 | if (NULL == w->net_handle) | ||
55 | { | ||
56 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to box network socket passed in from dbus.\n"); | ||
57 | GNUNET_abort_ (); | ||
58 | }; | ||
59 | } | ||
60 | else { | ||
61 | int fd = dbus_watch_get_unix_fd (watch); | ||
62 | if (-1 != fd) | ||
63 | { | ||
64 | w->file_handle = GNUNET_DISK_get_handle_from_int_fd (fd); | ||
65 | if (NULL == w->file_handle) | ||
66 | { | ||
67 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to box file handle passed in from dbus.\n"); | ||
68 | GNUNET_abort_ (); | ||
69 | }; | ||
70 | }; | ||
71 | }; | ||
72 | |||
73 | if (! w->net_handle && ! w->file_handle) | ||
74 | { | ||
75 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create watch. dbus_watch_get_socket returned %d\n", (int)sock); | ||
76 | GNUNET_abort_ (); | ||
77 | }; | ||
78 | |||
79 | return w; | ||
80 | }; | ||
81 | |||
82 | void | ||
83 | watch_ref ( | ||
84 | struct Watch *w) | ||
85 | { | ||
86 | w->ref_count++; | ||
87 | }; | ||
88 | |||
89 | void | ||
90 | watch_unref ( | ||
91 | struct Watch *w) | ||
92 | { | ||
93 | if (0 == w->ref_count) | ||
94 | { | ||
95 | LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unref watch with ref_count == 0\n"); | ||
96 | GNUNET_abort_ (); | ||
97 | }; | ||
98 | |||
99 | if (0 == --w->ref_count) | ||
100 | { | ||
101 | if (w->net_handle) | ||
102 | GNUNET_free (w->net_handle); | ||
103 | if (w->file_handle) | ||
104 | GNUNET_free (w->file_handle); | ||
105 | |||
106 | GNUNET_free (w); | ||
107 | } | ||
108 | }; | ||
109 | |||
110 | /* | ||
111 | * Callback called by the scheduler to tell libdbus that there is activity on | ||
112 | * one of its file descriptors. | ||
113 | * | ||
114 | * @param cls The watch | ||
115 | * @param tc the context given to us by the scheduler for this execution | ||
116 | */ | ||
117 | void | ||
118 | handle_watch ( | ||
119 | void *cls, | ||
120 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
121 | { | ||
122 | struct Watch *w = (struct Watch *)cls; | ||
123 | |||
124 | w->scheduled = false; | ||
125 | |||
126 | unsigned flags = 0; | ||
127 | if (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) | ||
128 | flags |= DBUS_WATCH_READABLE; | ||
129 | if (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) | ||
130 | flags |= DBUS_WATCH_WRITABLE; | ||
131 | if (flags) | ||
132 | { | ||
133 | dbus_watch_handle(w->watch, flags); | ||
134 | }; | ||
135 | |||
136 | if(w->ref_count > 1 && ! (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
137 | watch_schedule (w); | ||
138 | watch_unref (w); | ||
139 | }; | ||
140 | |||
141 | /* | ||
142 | * Ask the scheduler to watch this watch for activity. | ||
143 | * | ||
144 | * @param w The watch | ||
145 | * @return GNUNET_OK or GNUNET_SYSERR | ||
146 | */ | ||
147 | void | ||
148 | watch_schedule ( | ||
149 | struct Watch *w) | ||
150 | { | ||
151 | unsigned flags = dbus_watch_get_flags (w->watch); | ||
152 | |||
153 | if (! dbus_watch_get_enabled (w->watch)) | ||
154 | { | ||
155 | LOG (GNUNET_ERROR_TYPE_WARNING, "Tried to schedule watch that is disabled!\n"); | ||
156 | return; | ||
157 | }; | ||
158 | |||
159 | if (w->scheduled) | ||
160 | return; | ||
161 | |||
162 | if (w->net_handle) | ||
163 | { | ||
164 | w->task = GNUNET_SCHEDULER_add_net_with_priority( | ||
165 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
166 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
167 | w->net_handle, | ||
168 | flags & DBUS_WATCH_READABLE, | ||
169 | flags & DBUS_WATCH_WRITABLE, | ||
170 | handle_watch, | ||
171 | w); | ||
172 | w->scheduled = true; | ||
173 | watch_ref (w); | ||
174 | return; | ||
175 | }; | ||
176 | |||
177 | if (w->file_handle) | ||
178 | { | ||
179 | w->task = GNUNET_SCHEDULER_add_file_with_priority( | ||
180 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
181 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
182 | w->file_handle, | ||
183 | flags & DBUS_WATCH_READABLE, | ||
184 | flags & DBUS_WATCH_WRITABLE, | ||
185 | handle_watch, | ||
186 | w); | ||
187 | w->scheduled = true; | ||
188 | watch_ref (w); | ||
189 | return; | ||
190 | }; | ||
191 | |||
192 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to schedule watch.\n"); | ||
193 | GNUNET_abort_ (); | ||
194 | }; | ||
195 | |||
196 | /* | ||
197 | * Ask the scheduler to stop monitoring a watch either because we are shutting | ||
198 | * down or dbus has asked us to disable this watch. | ||
199 | * | ||
200 | * @param w The watch | ||
201 | * @return GNUNET_OK or GNUNET_SYSERR | ||
202 | */ | ||
203 | void | ||
204 | do_watch_unschedule ( | ||
205 | void *cls, | ||
206 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
207 | { | ||
208 | (void)tc; | ||
209 | struct Watch *w = (struct Watch *)cls; | ||
210 | |||
211 | if (! w->scheduled) | ||
212 | return; | ||
213 | |||
214 | void *ret = GNUNET_SCHEDULER_cancel (w->task); | ||
215 | if ((struct Watch *)ret != w) | ||
216 | LOG (GNUNET_ERROR_TYPE_WARNING, "Weird result unscheduling task. w == %p, GNUNET_SCHEDULER_cancel returned %p\n", w, ret); | ||
217 | |||
218 | watch_unref (w); | ||
219 | }; | ||
220 | |||
221 | void | ||
222 | watch_unschedule ( | ||
223 | struct Watch *w) | ||
224 | { | ||
225 | GNUNET_SCHEDULER_add_now (do_watch_unschedule, w); | ||
226 | }; | ||
227 | |||
228 | struct WatchIter * | ||
229 | watch_find (struct WatchIter *wi, DBusWatch *watch) | ||
230 | { | ||
231 | while (wi && wi->w->watch != watch) | ||
232 | wi = wi->next; | ||
233 | return wi; | ||
234 | }; | ||
235 | |||
diff --git a/src/lib/common/watch.h b/src/lib/common/watch.h new file mode 100644 index 0000000..ca60155 --- /dev/null +++ b/src/lib/common/watch.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef WATCH_H | ||
2 | #define WATCH_H | ||
3 | |||
4 | #include <dbus/dbus.h> | ||
5 | |||
6 | #include <gnunet/platform.h> | ||
7 | #include <gnunet/gnunet_common.h> | ||
8 | #include <gnunet/gnunet_scheduler_lib.h> | ||
9 | |||
10 | struct Watch; | ||
11 | |||
12 | struct WatchIter | ||
13 | { | ||
14 | struct WatchIter *next; | ||
15 | struct WatchIter *prev; | ||
16 | |||
17 | struct Watch *w; | ||
18 | }; | ||
19 | |||
20 | struct Watch *watch_create (DBusWatch *watch); | ||
21 | void watch_ref (struct Watch *w); | ||
22 | void watch_unref (struct Watch *w); | ||
23 | |||
24 | /* | ||
25 | * Schedule or schedule the scheduler to monitor dbus file descriptors. | ||
26 | */ | ||
27 | void watch_schedule (struct Watch *w); | ||
28 | void watch_unschedule (struct Watch *w); | ||
29 | void do_watch_unschedule (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
30 | |||
31 | struct WatchIter *watch_find (struct WatchIter *, DBusWatch *watch); | ||
32 | |||
33 | #endif | ||
34 | |||
diff --git a/src/lib/dht/Makefile.am b/src/lib/dht/Makefile.am new file mode 100644 index 0000000..2adb485 --- /dev/null +++ b/src/lib/dht/Makefile.am | |||
@@ -0,0 +1,16 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | lib_LTLIBRARIES = \ | ||
3 | libgnunetdhtdbus.la | ||
4 | |||
5 | libgnunetdhtdbus_la_SOURCES = \ | ||
6 | gnunet_dht_dbus_lib.c \ | ||
7 | gnunet_dht_dbus_lib_pop.c \ | ||
8 | gnunet_dht_dbus_lib_push.c | ||
9 | |||
10 | libgnunetdhtdbus_la_CFLAGS = \ | ||
11 | -I$(top_builddir)/src/lib/include \ | ||
12 | $(DBUS_CFLAGS) | ||
13 | |||
14 | libgnunetdhtdbus_la_LDFLAGS = \ | ||
15 | $(DBUS_LIBS) | ||
16 | |||
diff --git a/src/lib/dht/gnunet_dht_dbus_lib.c b/src/lib/dht/gnunet_dht_dbus_lib.c new file mode 100644 index 0000000..f01c9ea --- /dev/null +++ b/src/lib/dht/gnunet_dht_dbus_lib.c | |||
@@ -0,0 +1,13 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_dbus_lib.h" | ||
4 | #include "gnunet_dht_dbus_lib.h" | ||
5 | |||
6 | const struct GNUNET_DBUS_StringEnumPair GNUNET_DHT_DBUS_route_option_description[] = { | ||
7 | { "demultiplex_everywhere", GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE }, | ||
8 | { "record_route", GNUNET_DHT_RO_RECORD_ROUTE }, | ||
9 | { "find_peer", GNUNET_DHT_RO_FIND_PEER }, | ||
10 | { "bart", GNUNET_DHT_RO_BART }, | ||
11 | { NULL, 0} | ||
12 | }; | ||
13 | |||
diff --git a/src/lib/dht/gnunet_dht_dbus_lib_pop.c b/src/lib/dht/gnunet_dht_dbus_lib_pop.c new file mode 100644 index 0000000..e95fa6f --- /dev/null +++ b/src/lib/dht/gnunet_dht_dbus_lib_pop.c | |||
@@ -0,0 +1,16 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_dbus_lib.h" | ||
4 | #include "gnunet_dht_dbus_lib.h" | ||
5 | |||
6 | DBusMessage * | ||
7 | GNUNET_DHT_DBUS_pop_route_option ( | ||
8 | DBusMessage *message, | ||
9 | DBusMessageIter *iter, | ||
10 | const char *arg_name, | ||
11 | enum GNUNET_DHT_RouteOption *value) | ||
12 | { | ||
13 | return GNUNET_DBUS_pop_bitfield (message, iter, arg_name, (int *)value, GNUNET_DHT_DBUS_route_option_description); | ||
14 | }; | ||
15 | |||
16 | |||
diff --git a/src/lib/dht/gnunet_dht_dbus_lib_push.c b/src/lib/dht/gnunet_dht_dbus_lib_push.c new file mode 100644 index 0000000..b65314e --- /dev/null +++ b/src/lib/dht/gnunet_dht_dbus_lib_push.c | |||
@@ -0,0 +1,14 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_dbus_lib.h" | ||
4 | #include "gnunet_dht_dbus_lib.h" | ||
5 | |||
6 | void | ||
7 | GNUNET_DHT_DBUS_push_route_option ( | ||
8 | DBusMessage *message, | ||
9 | DBusMessageIter *iter, | ||
10 | const enum GNUNET_DHT_RouteOption *value) | ||
11 | { | ||
12 | return GNUNET_DBUS_push_bitfield (message, iter, (const int *)value, GNUNET_DHT_DBUS_route_option_description); | ||
13 | }; | ||
14 | |||
diff --git a/src/lib/gnsrecord/Makefile.am b/src/lib/gnsrecord/Makefile.am new file mode 100644 index 0000000..19add3b --- /dev/null +++ b/src/lib/gnsrecord/Makefile.am | |||
@@ -0,0 +1,17 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | lib_LTLIBRARIES = \ | ||
3 | libgnunetgnsrecorddbus.la | ||
4 | |||
5 | libgnunetgnsrecorddbus_la_SOURCES = \ | ||
6 | gnunet_gnsrecord_dbus_lib.c \ | ||
7 | gnunet_gnsrecord_dbus_lib_pop.c \ | ||
8 | gnunet_gnsrecord_dbus_lib_push.c | ||
9 | |||
10 | libgnunetgnsrecorddbus_la_CFLAGS = \ | ||
11 | -I$(top_builddir)/src/lib/include \ | ||
12 | $(DBUS_CFLAGS) | ||
13 | |||
14 | libgnunetgnsrecorddbus_la_LDFLAGS = \ | ||
15 | $(top_builddir)/src/lib/util/libgnunettimedbus.la \ | ||
16 | $(DBUS_LIBS) | ||
17 | |||
diff --git a/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib.c b/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib.c new file mode 100644 index 0000000..be8ba82 --- /dev/null +++ b/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_crypto_lib.h> | ||
6 | #include <gnunet/gnunet_time_lib.h> | ||
7 | #include <gnunet/gnunet_gnsrecord_lib.h> | ||
8 | |||
9 | #include "gnunet_dbus_lib.h" | ||
10 | |||
11 | const struct GNUNET_DBUS_StringEnumPair * | ||
12 | GNUNET_GNSRECORD_DBUS_describe_flags() | ||
13 | { | ||
14 | static const struct GNUNET_DBUS_StringEnumPair options[] = { | ||
15 | { "private", GNUNET_GNSRECORD_RF_PRIVATE }, | ||
16 | { "relative_expiration", GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION }, | ||
17 | { "shadow_record", GNUNET_GNSRECORD_RF_SHADOW_RECORD }, | ||
18 | { NULL, 0 } | ||
19 | }; | ||
20 | return options; | ||
21 | }; | ||
22 | |||
23 | |||
diff --git a/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib_pop.c b/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib_pop.c new file mode 100644 index 0000000..3e09d4b --- /dev/null +++ b/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib_pop.c | |||
@@ -0,0 +1,85 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_gnsrecord_dbus_lib.h" | ||
4 | |||
5 | DBusMessage * | ||
6 | GNUNET_GNSRECORD_DBUS_pop_type ( | ||
7 | DBusMessage *message, | ||
8 | DBusMessageIter *iter, | ||
9 | const char *arg_name, | ||
10 | uint32_t *value) | ||
11 | { | ||
12 | DBusMessageIter iter_sub; | ||
13 | DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
14 | if (ret) | ||
15 | return ret; | ||
16 | |||
17 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
18 | switch (arg_type) | ||
19 | { | ||
20 | case DBUS_TYPE_STRING: { | ||
21 | const char *string; | ||
22 | dbus_message_iter_get_basic (&iter_sub, &string); | ||
23 | *value = GNUNET_GNSRECORD_typename_to_number (string); | ||
24 | if (*value == UINT32_MAX) | ||
25 | { | ||
26 | return dbus_message_new_error_printf ( | ||
27 | message, | ||
28 | DBUS_ERROR_INVALID_ARGS, | ||
29 | "Bad argument for '%s'. %s is not a valid GNS record type. (Should be something like 'AAAA' or 'CNAME' etc.)", | ||
30 | arg_name, | ||
31 | string); | ||
32 | }; | ||
33 | return NULL; | ||
34 | }; | ||
35 | case DBUS_TYPE_UINT32: | ||
36 | dbus_message_iter_get_basic (&iter_sub, value); | ||
37 | return NULL; | ||
38 | default: | ||
39 | return dbus_message_new_error_printf ( | ||
40 | message, | ||
41 | DBUS_ERROR_INVALID_ARGS, | ||
42 | "Bad argument for '%s'. Variant should contain a string or uint32. Contains a %s.", | ||
43 | arg_name, | ||
44 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | DBusMessage * | ||
49 | GNUNET_GNSRECORD_DBUS_pop_flags ( | ||
50 | DBusMessage *message, | ||
51 | DBusMessageIter *iter, | ||
52 | const char *arg_name, | ||
53 | enum GNUNET_GNSRECORD_Flags *value) | ||
54 | { | ||
55 | return GNUNET_DBUS_pop_bitfield (message, iter, arg_name, (int *)value, GNUNET_GNSRECORD_DBUS_describe_flags ()); | ||
56 | }; | ||
57 | |||
58 | #if 0 | ||
59 | DBusMessage * | ||
60 | GNUNET_GNSRECORD_DBUS_pop_data ( | ||
61 | DBusMessage *message, | ||
62 | DBusMessageIter *iter, | ||
63 | const char *arg_name, | ||
64 | struct GNUNET_GNSRECORD_Data *value) | ||
65 | { | ||
66 | DBusMessageIter iter_sub; | ||
67 | DBusMessage *ret = GNUNET_DBUS_pop_enter_struct (message, iter, &iter_sub, arg_name); | ||
68 | if (ret) | ||
69 | return ret; | ||
70 | |||
71 | DBusMessageIter iter_sub_sub; | ||
72 | GNUNET_GNSRECORD_DBUS_pop_type (message, &iter_sub, "record_type", &value->record_type); | ||
73 | GNUNET_GNSRECORD_DBUS_pop_flags (message, &iter_sub, "flags", &value->flags); | ||
74 | GNUNET_DBUS_pop_enter_variant (message, &iter_sub, &iter_sub_sub); | ||
75 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub_sub); | ||
76 | switch (arg_type) | ||
77 | { | ||
78 | case DBUS_TYPE_STRING: { | ||
79 | const char *stringified; | ||
80 | dbus_message_iter_get_basic (&iter_sub_sub, &stringified); | ||
81 | int success = GNUNET_GNSRECORD_string_to_value (value->record_type, stringified, | ||
82 | |||
83 | #endif | ||
84 | |||
85 | |||
diff --git a/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib_push.c b/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib_push.c new file mode 100644 index 0000000..00dddc0 --- /dev/null +++ b/src/lib/gnsrecord/gnunet_gnsrecord_dbus_lib_push.c | |||
@@ -0,0 +1,88 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | |||
5 | #include "gnunet_gnsrecord_dbus_lib.h" | ||
6 | #include "gnunet_time_dbus_lib.h" | ||
7 | |||
8 | #define LOG(kind, ...) GNUNET_log_from(kind, "gnsrecord-dbus-push", __VA_ARGS__) | ||
9 | |||
10 | void | ||
11 | GNUNET_GNSRECORD_DBUS_push_type ( | ||
12 | DBusMessage *message, | ||
13 | DBusMessageIter *iter, | ||
14 | const uint32_t *value) | ||
15 | { | ||
16 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing GNSRECORD type\n"); | ||
17 | DBusMessageIter iter_sub; | ||
18 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
19 | { | ||
20 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
21 | const char *stringified = GNUNET_GNSRECORD_number_to_typename (*value); | ||
22 | GNUNET_DBUS_push_string (message, &iter_sub, &stringified); | ||
23 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
24 | } | ||
25 | else | ||
26 | { | ||
27 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_UINT32); | ||
28 | GNUNET_DBUS_push_uint32 (message, &iter_sub, value); | ||
29 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
30 | } | ||
31 | }; | ||
32 | |||
33 | void | ||
34 | GNUNET_GNSRECORD_DBUS_push_flags ( | ||
35 | DBusMessage *message, | ||
36 | DBusMessageIter *iter, | ||
37 | const enum GNUNET_GNSRECORD_Flags *value) | ||
38 | { | ||
39 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing GNUNET_GNSRECORD_Flags\n"); | ||
40 | GNUNET_DBUS_push_bitfield (message, iter, (const int *)value, GNUNET_GNSRECORD_DBUS_describe_flags ()); | ||
41 | }; | ||
42 | |||
43 | void | ||
44 | GNUNET_GNSRECORD_DBUS_push_data ( | ||
45 | DBusMessage *message, | ||
46 | DBusMessageIter *iter, | ||
47 | const struct GNUNET_GNSRECORD_Data *value) | ||
48 | { | ||
49 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing GNUNET_GNSRECORD_Data\n"); | ||
50 | DBusMessageIter iter_sub; | ||
51 | DBusMessageIter iter_sub_sub; | ||
52 | |||
53 | GNUNET_DBUS_push_open_struct (message, iter, &iter_sub); | ||
54 | GNUNET_GNSRECORD_DBUS_push_type (message, &iter_sub, &value->record_type); | ||
55 | GNUNET_GNSRECORD_DBUS_push_flags (message, &iter_sub, &value->flags); | ||
56 | |||
57 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
58 | { | ||
59 | GNUNET_DBUS_push_open_variant (message, &iter_sub, &iter_sub_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
60 | char *stringified = GNUNET_GNSRECORD_value_to_string (value->record_type, value->data, value->data_size); | ||
61 | const char *stringified_const = stringified; | ||
62 | GNUNET_DBUS_push_string (message, &iter_sub_sub, &stringified_const); | ||
63 | GNUNET_free (stringified); | ||
64 | GNUNET_DBUS_push_close_variant (message, &iter_sub, &iter_sub_sub); | ||
65 | } | ||
66 | else | ||
67 | { | ||
68 | GNUNET_DBUS_push_open_variant (message, &iter_sub, &iter_sub_sub, GNUNET_DBUS_SIGNATURE_ARRAY (GNUNET_DBUS_SIGNATURE_BYTE)); | ||
69 | GNUNET_DBUS_push_byte_array (message, &iter_sub_sub, (const unsigned char *)value->data, value->data_size); | ||
70 | GNUNET_DBUS_push_close_variant (message, &iter_sub, &iter_sub_sub); | ||
71 | }; | ||
72 | |||
73 | if (value->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) | ||
74 | { | ||
75 | struct GNUNET_TIME_Relative expiration_time; | ||
76 | expiration_time.rel_value_us = value->expiration_time; | ||
77 | GNUNET_TIME_DBUS_push_relative (message, &iter_sub, &expiration_time); | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | struct GNUNET_TIME_Absolute expiration_time; | ||
82 | expiration_time.abs_value_us = value->expiration_time; | ||
83 | GNUNET_TIME_DBUS_push_absolute (message, &iter_sub, &expiration_time); | ||
84 | }; | ||
85 | GNUNET_DBUS_push_close_struct (message, iter, &iter_sub); | ||
86 | } | ||
87 | |||
88 | |||
diff --git a/src/lib/include/gnunet_block_dbus_lib.h b/src/lib/include/gnunet_block_dbus_lib.h new file mode 100644 index 0000000..acdfc99 --- /dev/null +++ b/src/lib/include/gnunet_block_dbus_lib.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef GNUNET_BLOCK_DBUS_LIB_H | ||
2 | #define GNUNET_BLOCK_DBUS_LIB_H | ||
3 | |||
4 | #include <gnunet_dbus_lib.h> | ||
5 | |||
6 | /** | ||
7 | * A {NULL, 0}-terminated list of textual descriptions of `GNUNET_BLOCK_Type` | ||
8 | * enum variants. Used for converting back-and-forth between `GNUNET_DBUS_Type` | ||
9 | * and `const char *` | ||
10 | */ | ||
11 | extern const struct GNUNET_DBUS_StringEnumPair GNUNET_BLOCK_DBUS_type_description[]; | ||
12 | |||
13 | #include "gnunet_block_dbus_lib_pop.h" | ||
14 | #include "gnunet_block_dbus_lib_push.h" | ||
15 | #include "gnunet_block_dbus_lib_signature.h" | ||
16 | |||
17 | #endif | ||
18 | |||
diff --git a/src/lib/include/gnunet_block_dbus_lib_pop.h b/src/lib/include/gnunet_block_dbus_lib_pop.h new file mode 100644 index 0000000..ac8ce30 --- /dev/null +++ b/src/lib/include/gnunet_block_dbus_lib_pop.h | |||
@@ -0,0 +1,24 @@ | |||
1 | #ifndef GNUNET_BLOCK_DBUS_LIB_POP_H | ||
2 | #define GNUNET_BLOCK_DBUS_LIB_POP_H | ||
3 | |||
4 | #include <dbus/dbus.h> | ||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_block_lib.h> | ||
8 | |||
9 | #include "gnunet_dbus_lib_method_context.h" | ||
10 | |||
11 | /** | ||
12 | * Pop a GNUNET_DBUS_Type off of a DBusMessage, moving the iterator. | ||
13 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
14 | * message is missing or the wrong type. | ||
15 | */ | ||
16 | DBusMessage * | ||
17 | GNUNET_BLOCK_DBUS_pop_type ( | ||
18 | DBusMessage *message, | ||
19 | DBusMessageIter *iter, | ||
20 | const char *arg_name, | ||
21 | enum GNUNET_BLOCK_Type *value); | ||
22 | |||
23 | #endif | ||
24 | |||
diff --git a/src/lib/include/gnunet_block_dbus_lib_push.h b/src/lib/include/gnunet_block_dbus_lib_push.h new file mode 100644 index 0000000..27d78c3 --- /dev/null +++ b/src/lib/include/gnunet_block_dbus_lib_push.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef GNUNET_BLOCK_DBUS_LIB_PUSH_H | ||
2 | #define GNUNET_BLOCK_DBUS_LIB_PUSH_H | ||
3 | |||
4 | #include "gnunet_block_dbus_lib.h" | ||
5 | |||
6 | /** | ||
7 | * Push a GNUNET_BLOCK_Type onto a DBusMessage, advancing the iterator. | ||
8 | */ | ||
9 | void | ||
10 | GNUNET_BLOCK_DBUS_push_type ( | ||
11 | DBusMessage *message, | ||
12 | DBusMessageIter *iter, | ||
13 | const enum GNUNET_BLOCK_Type *value); | ||
14 | |||
15 | #endif | ||
16 | |||
diff --git a/src/lib/include/gnunet_block_dbus_lib_signature.h b/src/lib/include/gnunet_block_dbus_lib_signature.h new file mode 100644 index 0000000..f6970ec --- /dev/null +++ b/src/lib/include/gnunet_block_dbus_lib_signature.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef GNUNET_BLOCK_DBUS_LIB_SIGNATURE_H | ||
2 | #define GNUNET_BLOCK_DBUS_LIB_SIGNATURE_H | ||
3 | |||
4 | #define GNUNET_BLOCK_DBUS_SIGNATURE_TYPE GNUNET_DBUS_SIGNATURE_VARIANT | ||
5 | |||
6 | #endif | ||
7 | |||
diff --git a/src/lib/include/gnunet_crypto_dbus_lib.h b/src/lib/include/gnunet_crypto_dbus_lib.h new file mode 100644 index 0000000..ddcc653 --- /dev/null +++ b/src/lib/include/gnunet_crypto_dbus_lib.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef GNUNET_CRYPTO_DBUS_LIB_H | ||
2 | #define GNUNET_CRYPTO_DBUS_LIB_H | ||
3 | |||
4 | #include <gnunet_dbus_lib.h> | ||
5 | |||
6 | #include "gnunet_crypto_dbus_lib_push.h" | ||
7 | #include "gnunet_crypto_dbus_lib_pop.h" | ||
8 | #include "gnunet_crypto_dbus_lib_signature.h" | ||
9 | |||
10 | #endif | ||
11 | |||
diff --git a/src/lib/include/gnunet_crypto_dbus_lib_pop.h b/src/lib/include/gnunet_crypto_dbus_lib_pop.h new file mode 100644 index 0000000..7fe086a --- /dev/null +++ b/src/lib/include/gnunet_crypto_dbus_lib_pop.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef GNUNET_CRYPTO_DBUS_LIB_POP_H | ||
2 | #define GNUNET_CRYPTO_DBUS_LIB_POP_H | ||
3 | |||
4 | #include <gnunet/platform.h> | ||
5 | #include <gnunet/gnunet_common.h> | ||
6 | #include <gnunet/gnunet_crypto_lib.h> | ||
7 | |||
8 | /** | ||
9 | * Pop a GNUNET_CRYPT_EcdsaPublicKey off of a DBusMessage, moving the iterator. | ||
10 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
11 | * message is missing or the wrong type. | ||
12 | */ | ||
13 | DBusMessage * | ||
14 | GNUNET_CRYPTO_DBUS_pop_ecdsa_public_key ( | ||
15 | DBusMessage *message, | ||
16 | DBusMessageIter *iter, | ||
17 | const char *arg_name, | ||
18 | struct GNUNET_CRYPTO_EcdsaPublicKey *value); | ||
19 | |||
20 | /** | ||
21 | * Pop a GNUNET_CRYPTO_EddsaPublicKey off a DBusMessage, moving the iterator. | ||
22 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
23 | * message is missing or the wrong type. | ||
24 | */ | ||
25 | DBusMessage * | ||
26 | GNUNET_CRYPTO_DBUS_pop_eddsa_public_key ( | ||
27 | DBusMessage *message, | ||
28 | DBusMessageIter *iter, | ||
29 | const char *arg_name, | ||
30 | struct GNUNET_CRYPTO_EddsaPublicKey *value); | ||
31 | |||
32 | #endif | ||
33 | |||
diff --git a/src/lib/include/gnunet_crypto_dbus_lib_push.h b/src/lib/include/gnunet_crypto_dbus_lib_push.h new file mode 100644 index 0000000..80b15d6 --- /dev/null +++ b/src/lib/include/gnunet_crypto_dbus_lib_push.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef GNUNET_CRYPTO_DBUS_LIB_PUSH_H | ||
2 | #define GNUNET_CRYPTO_DBUS_LIB_PUSH_H | ||
3 | |||
4 | #include <gnunet/platform.h> | ||
5 | #include <gnunet/gnunet_common.h> | ||
6 | #include <gnunet/gnunet_crypto_lib.h> | ||
7 | |||
8 | /** | ||
9 | * Push a GNUNET_CRYPTO_EcdsaPublicKey onto a DBusMessage, advancing the iterator. | ||
10 | */ | ||
11 | void | ||
12 | GNUNET_CRYPTO_DBUS_push_ecdsa_public_key ( | ||
13 | DBusMessage *message, | ||
14 | DBusMessageIter *iter, | ||
15 | const struct GNUNET_CRYPTO_EcdsaPublicKey *value); | ||
16 | |||
17 | /** | ||
18 | * Push a GNUNET_CRYPTO_EddsaPublicKey onto a DBusMessage, advancing the iterator. | ||
19 | */ | ||
20 | void | ||
21 | GNUNET_CRYPTO_DBUS_push_eddsa_public_key ( | ||
22 | DBusMessage *message, | ||
23 | DBusMessageIter *iter, | ||
24 | const struct GNUNET_CRYPTO_EddsaPublicKey *value); | ||
25 | |||
26 | #endif | ||
27 | |||
diff --git a/src/lib/include/gnunet_crypto_dbus_lib_signature.h b/src/lib/include/gnunet_crypto_dbus_lib_signature.h new file mode 100644 index 0000000..94fed6e --- /dev/null +++ b/src/lib/include/gnunet_crypto_dbus_lib_signature.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef GNUNET_CRYPTO_DBUS_LIB_SIGNATURE_H | ||
2 | #define GNUNET_CRYPTO_DBUS_LIB_SIGNATURE_H | ||
3 | |||
4 | #include "gnunet_dbus_lib.h" | ||
5 | |||
6 | #define GNUNET_CRYPTO_DBUS_SIGNATURE_ECDSA_SIGNATURE \ | ||
7 | GNUNET_DBUS_SIGNATURE_STRUCT ( \ | ||
8 | GNUNET_DBUS_SIGNATURE_VARIANT \ | ||
9 | GNUNET_DBUS_SIGNATURE_VARIANT \ | ||
10 | ) | ||
11 | |||
12 | #define GNUNET_CRYPTO_DBUS_SIGNATURE_ECC_SIGNATURE_PURPOSE \ | ||
13 | GNUNET_DBUS_SIGNATURE_STRUCT ( \ | ||
14 | GNUNET_DBUS_SIGNATURE_UINT32 \ | ||
15 | GNUNET_DBUS_SIGNATURE_UINT32 \ | ||
16 | ) | ||
17 | |||
18 | #define GNUNET_CRYPTO_DBUS_SIGNATURE_ECDSA_PUBLIC_KEY GNUNET_DBUS_SIGNATURE_VARIANT | ||
19 | #define GNUNET_CRYPTO_DBUS_SIGNATURE_EDDSA_PUBLIC_KEY GNUNET_DBUS_SIGNATURE_VARIANT | ||
20 | |||
21 | #endif | ||
22 | |||
diff --git a/src/lib/include/gnunet_dbus_lib.h b/src/lib/include/gnunet_dbus_lib.h new file mode 100644 index 0000000..7cf5143 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_H | ||
2 | #define GNUNET_DBUS_LIB_H | ||
3 | |||
4 | /** | ||
5 | * Used to assign a textual description to an enum variant. | ||
6 | * eg. {"dht_hello", GNUNET_BLOCK_TYPE_DHT_HELLO}. | ||
7 | * Generally stored in an array, terminated by {NULL, 0}. | ||
8 | */ | ||
9 | struct GNUNET_DBUS_StringEnumPair { | ||
10 | const char *name; | ||
11 | const int value; | ||
12 | }; | ||
13 | |||
14 | #include "gnunet_dbus_lib_service.h" | ||
15 | #include "gnunet_dbus_lib_object.h" | ||
16 | #include "gnunet_dbus_lib_object_path.h" | ||
17 | #include "gnunet_dbus_lib_interface.h" | ||
18 | #include "gnunet_dbus_lib_method.h" | ||
19 | #include "gnunet_dbus_lib_signal.h" | ||
20 | #include "gnunet_dbus_lib_arg.h" | ||
21 | #include "gnunet_dbus_lib_message.h" | ||
22 | #include "gnunet_dbus_lib_method_context.h" | ||
23 | #include "gnunet_dbus_lib_client.h" | ||
24 | #include "gnunet_dbus_lib_signature.h" | ||
25 | #include "gnunet_dbus_lib_push.h" | ||
26 | #include "gnunet_dbus_lib_pop.h" | ||
27 | |||
28 | #endif | ||
29 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_arg.h b/src/lib/include/gnunet_dbus_lib_arg.h new file mode 100644 index 0000000..34a8a68 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_arg.h | |||
@@ -0,0 +1,75 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_ARG_H | ||
2 | #define GNUNET_DBUS_LIB_ARG_H | ||
3 | |||
4 | /** | ||
5 | * Used to represent an argument to a DBus method or signal. An argument | ||
6 | * consists of a name and a DBus type signature. | ||
7 | */ | ||
8 | struct GNUNET_DBUS_Arg; | ||
9 | |||
10 | /** | ||
11 | * An iterable, doubly-linked-list of GNUNET_DBUS_Arg. | ||
12 | */ | ||
13 | struct GNUNET_DBUS_ArgIterator | ||
14 | { | ||
15 | /* linked list */ | ||
16 | struct GNUNET_DBUS_ArgIterator *next; | ||
17 | struct GNUNET_DBUS_ArgIterator *prev; | ||
18 | |||
19 | struct GNUNET_DBUS_Arg *arg; | ||
20 | }; | ||
21 | |||
22 | /** | ||
23 | * Create a GNUNET_DBUS_Arg with the given name, DBus type signature and a | ||
24 | * reference count of one. | ||
25 | */ | ||
26 | struct GNUNET_DBUS_Arg * | ||
27 | GNUNET_DBUS_arg_create ( | ||
28 | const char *name, | ||
29 | const char *signature); | ||
30 | |||
31 | /** | ||
32 | * Increase the reference count of this GNUNET_DBUS_Arg by one. | ||
33 | */ | ||
34 | void | ||
35 | GNUNET_DBUS_arg_ref ( | ||
36 | struct GNUNET_DBUS_Arg *arg); | ||
37 | |||
38 | /** | ||
39 | * Decrease the reference count of this GNUNET_DBUS_Arg by one. Will free the | ||
40 | * GNNET_DBUS_Arg if the reference count reaches zero. | ||
41 | */ | ||
42 | void | ||
43 | GNUNET_DBUS_arg_unref ( | ||
44 | struct GNUNET_DBUS_Arg *arg); | ||
45 | |||
46 | /** | ||
47 | * Get the name of this GNUNET_DBUS_Arg. | ||
48 | */ | ||
49 | const char * | ||
50 | GNUNET_DBUS_arg_get_name ( | ||
51 | const struct GNUNET_DBUS_Arg *arg); | ||
52 | |||
53 | /** | ||
54 | * Get the DBus type signature of this GNUNET_DBUS_Arg. | ||
55 | */ | ||
56 | const char * | ||
57 | GNUNET_DBUS_arg_get_signature ( | ||
58 | const struct GNUNET_DBUS_Arg *arg); | ||
59 | |||
60 | #if 0 | ||
61 | void | ||
62 | GNUNET_DBUS_arg_pop_message ( | ||
63 | const struct GNUNET_DBUS_Arg *arg, | ||
64 | DBusMessageIter *dbus_message_iter, | ||
65 | void *value); | ||
66 | |||
67 | void | ||
68 | GNUNET_DBUS_arg_push_message ( | ||
69 | const struct GNUNET_DBUS_Arg *arg, | ||
70 | DBusMessageIter *dbus_message_iter, | ||
71 | va_list vl); | ||
72 | #endif | ||
73 | |||
74 | #endif | ||
75 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_client.h b/src/lib/include/gnunet_dbus_lib_client.h new file mode 100644 index 0000000..413a0c3 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_client.h | |||
@@ -0,0 +1,105 @@ | |||
1 | #ifndef GNUNET_DBUS_CLIENT_H | ||
2 | #define GNUNET_DBUS_CLIENT_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | |||
6 | /** | ||
7 | * Used by services to keep track of connected clients. Can associate an | ||
8 | * arbitrary piece of data with each client. | ||
9 | */ | ||
10 | struct GNUNET_DBUS_Client; | ||
11 | |||
12 | /** | ||
13 | * An iterable, double-linked-list of GNUNET_DBUS_Client | ||
14 | */ | ||
15 | struct GNUNET_DBUS_ClientIterator | ||
16 | { | ||
17 | struct GNUNET_DBUS_ClientIterator *next; | ||
18 | struct GNUNET_DBUS_ClientIterator *prev; | ||
19 | |||
20 | struct GNUNET_DBUS_Client *client; | ||
21 | }; | ||
22 | |||
23 | /** | ||
24 | * Create a GNUNET_DBUS_Client with the given DBus unique name (eg. "1:23"). | ||
25 | */ | ||
26 | struct GNUNET_DBUS_Client * | ||
27 | GNUNET_DBUS_client_create ( | ||
28 | const char *unique_name); | ||
29 | |||
30 | /** | ||
31 | * Increase the reference count of this GNUNET_DBUS_Client by one. | ||
32 | */ | ||
33 | void | ||
34 | GNUNET_DBUS_client_ref ( | ||
35 | struct GNUNET_DBUS_Client *client); | ||
36 | |||
37 | /** | ||
38 | * Decrease the reference count of this GNUNET_DBUS_Client by one. Will free | ||
39 | * the GNUNET_DBUS_Client if the reference count reaches zero. | ||
40 | */ | ||
41 | void | ||
42 | GNUNET_DBUS_client_unref ( | ||
43 | struct GNUNET_DBUS_Client *client); | ||
44 | |||
45 | /* | ||
46 | * Get the DBus unique name of this client (eg. "1:23"). | ||
47 | */ | ||
48 | const char * | ||
49 | GNUNET_DBUS_client_get_unique_name ( | ||
50 | const struct GNUNET_DBUS_Client *client); | ||
51 | |||
52 | /** | ||
53 | * Set the arbitrary piece of data associated with the client. | ||
54 | */ | ||
55 | void | ||
56 | GNUNET_DBUS_client_set_data ( | ||
57 | struct GNUNET_DBUS_Client *client, | ||
58 | void *data); | ||
59 | |||
60 | /** | ||
61 | * Get the arbitrary piece of data associated with the client. | ||
62 | */ | ||
63 | void * | ||
64 | GNUNET_DBUS_client_get_data ( | ||
65 | const struct GNUNET_DBUS_Client *client); | ||
66 | /** | ||
67 | * Set whether this client prefers data to be pretty-encoded for transmission | ||
68 | * over DBus. For example, the enum variant GNUNET_BLOCK_TYPE_DHT_HELLO will be | ||
69 | * sent over-the-wire to this client as a DBus uint32 or as a the DBus string | ||
70 | * "dht_hello" depending on this flag. | ||
71 | */ | ||
72 | void | ||
73 | GNUNET_DBUS_client_set_prefers_pretty_encodings ( | ||
74 | struct GNUNET_DBUS_Client *client, | ||
75 | bool prefers_pretty_encodings); | ||
76 | |||
77 | /** | ||
78 | * Get whether this client prefers data to be pretty-encoded for transmission | ||
79 | * over DBus. For example, the enum variant GNUNET_BLOCK_TYPE_DHT_HELLO will be | ||
80 | * sent over-the-wire to this client as a DBus uint32 or as a the DBus string | ||
81 | * "dht_hello" depending on this flag. | ||
82 | */ | ||
83 | bool | ||
84 | GNUNET_DBUS_client_get_prefers_pretty_encodings ( | ||
85 | const struct GNUNET_DBUS_Client *client); | ||
86 | |||
87 | DBusMessage * | ||
88 | GNUNET_DBUS_client_create_method_call ( | ||
89 | struct GNUNET_DBUS_Client *client, | ||
90 | const char *object_path, | ||
91 | const char *interface, | ||
92 | const char *method, | ||
93 | bool pretty, | ||
94 | void (*return_callback)(DBusMessage *message)); | ||
95 | |||
96 | DBusMessage * | ||
97 | GNUNET_DBUS_client_create_unicast_signal ( | ||
98 | struct GNUNET_DBUS_Client *client, | ||
99 | const char *object_path, | ||
100 | const char *interface, | ||
101 | const char *signal, | ||
102 | bool pretty); | ||
103 | |||
104 | #endif | ||
105 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_interface.h b/src/lib/include/gnunet_dbus_lib_interface.h new file mode 100644 index 0000000..83cd598 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_interface.h | |||
@@ -0,0 +1,104 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_INTERFACE_H | ||
2 | #define GNUNET_DBUS_LIB_INTERFACE_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | |||
6 | /** | ||
7 | * Represents a DBus interface. An interface consists of a set of methods and | ||
8 | * signals. | ||
9 | */ | ||
10 | struct GNUNET_DBUS_Interface; | ||
11 | |||
12 | #include "gnunet_dbus_lib_object.h" | ||
13 | #include "gnunet_dbus_lib_method.h" | ||
14 | #include "gnunet_dbus_lib_method_context.h" | ||
15 | #include "gnunet_dbus_lib_signal.h" | ||
16 | |||
17 | struct GNUNET_DBUS_InterfaceIterator | ||
18 | { | ||
19 | /* linked list */ | ||
20 | struct GNUNET_DBUS_InterfaceIterator *next; | ||
21 | struct GNUNET_DBUS_InterfaceIterator *prev; | ||
22 | |||
23 | struct GNUNET_DBUS_Interface *interface; | ||
24 | }; | ||
25 | |||
26 | /** | ||
27 | * Create a DBus interface with the given name. After populating this interface | ||
28 | * with methods and signals it can be added to an object with | ||
29 | * GNUNET_DBUS_object_add_interface. | ||
30 | */ | ||
31 | struct GNUNET_DBUS_Interface * | ||
32 | GNUNET_DBUS_interface_create ( | ||
33 | const char *name); | ||
34 | |||
35 | /** | ||
36 | * Increase the reference count of this GNUNET_DBUS_Interface by one. | ||
37 | */ | ||
38 | void | ||
39 | GNUNET_DBUS_interface_ref ( | ||
40 | struct GNUNET_DBUS_Interface *interface); | ||
41 | |||
42 | /** | ||
43 | * Decrease the reference count of this GNUNET_DBUS_Interface by one. | ||
44 | */ | ||
45 | void | ||
46 | GNUNET_DBUS_interface_unref ( | ||
47 | struct GNUNET_DBUS_Interface *interface); | ||
48 | |||
49 | /** | ||
50 | * Add a method to this interface. This will increase the reference count of | ||
51 | * the GNUNET_DBUS_Method by one. | ||
52 | */ | ||
53 | void | ||
54 | GNUNET_DBUS_interface_add_method ( | ||
55 | struct GNUNET_DBUS_Interface *interface, | ||
56 | struct GNUNET_DBUS_Method *method); | ||
57 | |||
58 | /** | ||
59 | * Add a signal to this interface. This will increase the reference count of | ||
60 | * the GNUNET_DBUS_Signal by one. | ||
61 | */ | ||
62 | void | ||
63 | GNUNET_DBUS_interface_add_signal ( | ||
64 | struct GNUNET_DBUS_Interface *interface, | ||
65 | struct GNUNET_DBUS_Signal *signal); | ||
66 | |||
67 | /** | ||
68 | * Get the name of this GNUNET_DBUS_Interface. | ||
69 | */ | ||
70 | const char * | ||
71 | GNUNET_DBUS_interface_get_name ( | ||
72 | const struct GNUNET_DBUS_Interface *interface); | ||
73 | |||
74 | /** | ||
75 | * Iterate over the methods of this GNUNET_DBUS_Interface. | ||
76 | */ | ||
77 | const struct GNUNET_DBUS_MethodIterator * | ||
78 | GNUNET_DBUS_interface_iterate_methods ( | ||
79 | const struct GNUNET_DBUS_Interface *interface); | ||
80 | |||
81 | /** | ||
82 | * Iterate over the signals of this GNUNET_DBUS_Interface. | ||
83 | */ | ||
84 | const struct GNUNET_DBUS_SignalIterator * | ||
85 | GNUNET_DBUS_interface_iterate_signals ( | ||
86 | const struct GNUNET_DBUS_Interface *interface); | ||
87 | |||
88 | /** | ||
89 | * Returns the org.freedesktop.DBus.Introspectable interface. | ||
90 | */ | ||
91 | struct GNUNET_DBUS_Interface * | ||
92 | GNUNET_DBUS_interface_introspectable (); | ||
93 | |||
94 | /** | ||
95 | * Return the position in the given linked-list of the GNUNET_DBUS_Interface | ||
96 | * with the given name. Returns NULL if the interface could not be found. | ||
97 | */ | ||
98 | const struct GNUNET_DBUS_InterfaceIterator * | ||
99 | GNUNET_DBUS_interface_find ( | ||
100 | const struct GNUNET_DBUS_InterfaceIterator *int_it, | ||
101 | const char *name); | ||
102 | |||
103 | #endif | ||
104 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_message.h b/src/lib/include/gnunet_dbus_lib_message.h new file mode 100644 index 0000000..e575823 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_message.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_MESSAGE_H | ||
2 | #define GNUNET_DBUS_LIB_MESSAGE_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | #include <dbus/dbus.h> | ||
6 | |||
7 | #include "gnunet_dbus_lib_client.h" | ||
8 | |||
9 | /** | ||
10 | * Get the value of this message's pretty-encoding flag. This flag controls | ||
11 | * whether data pushed to the message will be pretty-encoded for transmission | ||
12 | * over DBus. | ||
13 | */ | ||
14 | bool | ||
15 | GNUNET_DBUS_message_get_pretty ( | ||
16 | DBusMessage *message); | ||
17 | |||
18 | /** | ||
19 | * Set the value of this message's pretty-encoding flag. This flag controls | ||
20 | * whether data pushed to the message will be pretty-encoded for transmission | ||
21 | * over DBus. | ||
22 | */ | ||
23 | void | ||
24 | GNUNET_DBUS_message_set_pretty ( | ||
25 | DBusMessage *message, | ||
26 | bool pretty); | ||
27 | |||
28 | /** | ||
29 | * Set the destination of this message to the DBus address of the | ||
30 | * GNUNET_DBUS_Client. | ||
31 | */ | ||
32 | void | ||
33 | GNUNET_DBUS_message_set_destination ( | ||
34 | DBusMessage *message, | ||
35 | struct GNUNET_DBUS_Client *client); | ||
36 | |||
37 | /** | ||
38 | * Set the destination of this message to NULL. | ||
39 | */ | ||
40 | void | ||
41 | GNUNET_DBUS_message_unset_destination ( | ||
42 | DBusMessage *message); | ||
43 | |||
44 | #endif | ||
45 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_method.h b/src/lib/include/gnunet_dbus_lib_method.h new file mode 100644 index 0000000..9b47fcf --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_method.h | |||
@@ -0,0 +1,110 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_METHOD_H | ||
2 | #define GNUNET_DBUS_LIB_METHOD_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | |||
6 | /** | ||
7 | * Represents a DBus method. Consists of a linked-list of args and return args | ||
8 | * of type GNUNET_DBUS_Arg. | ||
9 | */ | ||
10 | struct GNUNET_DBUS_Method; | ||
11 | |||
12 | #include "gnunet_dbus_lib_object.h" | ||
13 | #include "gnunet_dbus_lib_method_context.h" | ||
14 | |||
15 | /** | ||
16 | * An iterable, double-linked list of GNUNET_DBUS_Method. | ||
17 | */ | ||
18 | struct GNUNET_DBUS_MethodIterator | ||
19 | { | ||
20 | /* linked list */ | ||
21 | struct GNUNET_DBUS_MethodIterator *next; | ||
22 | struct GNUNET_DBUS_MethodIterator *prev; | ||
23 | |||
24 | struct GNUNET_DBUS_Method *method; | ||
25 | }; | ||
26 | |||
27 | /** | ||
28 | * Create a new GNUNET_DBUS_Method with the given name. The underlying_method | ||
29 | * function will be called whenever this method is called via DBus. After | ||
30 | * creating a method you need to populate it the args and return args before | ||
31 | * binding it to an interface with GNUNET_DBUS_interface_add_method. | ||
32 | */ | ||
33 | struct GNUNET_DBUS_Method * | ||
34 | GNUNET_DBUS_method_create ( | ||
35 | const char *name, | ||
36 | void (*underlying_method)(struct GNUNET_DBUS_MethodContext *mc)); | ||
37 | |||
38 | /** | ||
39 | * Increase the reference count of this GNUNET_DBUS_Method by one. | ||
40 | */ | ||
41 | void | ||
42 | GNUNET_DBUS_method_ref ( | ||
43 | struct GNUNET_DBUS_Method *method); | ||
44 | |||
45 | /** | ||
46 | * Decrease the reference count of this GNUNET_DBUS_Method by one. Will free | ||
47 | * the method if the reference count reaches zero. | ||
48 | */ | ||
49 | void | ||
50 | GNUNET_DBUS_method_unref ( | ||
51 | struct GNUNET_DBUS_Method *method); | ||
52 | |||
53 | /** | ||
54 | * Add an argument with the given name and type signature to this method. | ||
55 | */ | ||
56 | void | ||
57 | GNUNET_DBUS_method_add_arg ( | ||
58 | struct GNUNET_DBUS_Method *method, | ||
59 | const char *name, | ||
60 | const char *signature); | ||
61 | |||
62 | /** | ||
63 | * Add a return argument with the given name and type signature to this method. | ||
64 | */ | ||
65 | void | ||
66 | GNUNET_DBUS_method_add_return_arg ( | ||
67 | struct GNUNET_DBUS_Method *method, | ||
68 | const char *name, | ||
69 | const char *signature); | ||
70 | |||
71 | /** | ||
72 | * Get the name of this method. | ||
73 | */ | ||
74 | const char * | ||
75 | GNUNET_DBUS_method_get_name ( | ||
76 | const struct GNUNET_DBUS_Method *method); | ||
77 | |||
78 | /** | ||
79 | * Iterate over the arguments of this GNUNET_DBUS_Method. | ||
80 | */ | ||
81 | const struct GNUNET_DBUS_ArgIterator * | ||
82 | GNUNET_DBUS_method_iterate_args ( | ||
83 | const struct GNUNET_DBUS_Method *method); | ||
84 | /* | ||
85 | * Iterate over the return arguments of this GNUNET_DBUS_Method. | ||
86 | */ | ||
87 | const struct GNUNET_DBUS_ArgIterator * | ||
88 | GNUNET_DBUS_method_iterate_return_args ( | ||
89 | const struct GNUNET_DBUS_Method *method); | ||
90 | |||
91 | /** | ||
92 | * Call this method with the supplied GNUNET_DBUS_MethodContext. | ||
93 | */ | ||
94 | void | ||
95 | GNUNET_DBUS_method_call ( | ||
96 | struct GNUNET_DBUS_Method *method, | ||
97 | struct GNUNET_DBUS_MethodContext *mc); | ||
98 | |||
99 | /** | ||
100 | * Find a GNUNET_DBUS_Method with the given name in the supplied iterator. | ||
101 | * Returns the position in the iterator of the method or NULL if it could not | ||
102 | * be found. | ||
103 | */ | ||
104 | const struct GNUNET_DBUS_MethodIterator * | ||
105 | GNUNET_DBUS_method_find ( | ||
106 | const struct GNUNET_DBUS_MethodIterator *meth_it, | ||
107 | const char *name); | ||
108 | |||
109 | #endif | ||
110 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_method_context.h b/src/lib/include/gnunet_dbus_lib_method_context.h new file mode 100644 index 0000000..27b5789 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_method_context.h | |||
@@ -0,0 +1,115 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_METHOD_CONTEXT_H | ||
2 | #define GNUNET_DBUS_LIB_METHOD_CONTEXT_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | |||
6 | #include <dbus/dbus.h> | ||
7 | |||
8 | /** | ||
9 | * An object of this type is passed to every function bound to a | ||
10 | * GNUNET_DBUS_Method when it is called via DBus. | ||
11 | */ | ||
12 | struct GNUNET_DBUS_MethodContext | ||
13 | { | ||
14 | /** | ||
15 | * The client calling this method. | ||
16 | */ | ||
17 | struct GNUNET_DBUS_Client *client; | ||
18 | |||
19 | /** | ||
20 | * The service that this method was called on. This is necessary as the | ||
21 | * process might be running several DBus services all advertising the same | ||
22 | * method. | ||
23 | */ | ||
24 | struct GNUNET_DBUS_Service *service; | ||
25 | |||
26 | /** | ||
27 | * The object that this method was called on. | ||
28 | */ | ||
29 | struct GNUNET_DBUS_Object *object; | ||
30 | |||
31 | /** | ||
32 | * The interface that this method was called on. | ||
33 | */ | ||
34 | struct GNUNET_DBUS_Interface *interface; | ||
35 | |||
36 | /** | ||
37 | * The method that was called. Necessary because multiple DBus methods may be | ||
38 | * bound to a single internal function. | ||
39 | */ | ||
40 | struct GNUNET_DBUS_Method *method; | ||
41 | |||
42 | /** | ||
43 | * The method-call message sent by the client. | ||
44 | */ | ||
45 | DBusMessage *message; | ||
46 | |||
47 | /** | ||
48 | * Whether the client expects a reply to this message. If the user of this | ||
49 | * API tries to send a reply to the client via this | ||
50 | * GNUNET_DBUS_MethodContext, the reply will not be sent if this flag is | ||
51 | * unset. | ||
52 | */ | ||
53 | bool expects_reply; | ||
54 | |||
55 | /** | ||
56 | * Whether we have already replied to this DBus method-call message. | ||
57 | */ | ||
58 | bool replied; | ||
59 | |||
60 | /** | ||
61 | * The reference count of the GNUNET_DBUS_MethodContext. | ||
62 | */ | ||
63 | unsigned ref_count; | ||
64 | }; | ||
65 | |||
66 | /** | ||
67 | * Create a GNUNET_DBUS_MethodContext from the supplied DBus method-call | ||
68 | * message. The message must have been sent by the given client to the given | ||
69 | * service+object+interface+method. This will increase the reference count of | ||
70 | * the DBusMessage but not the other supplied objects. | ||
71 | */ | ||
72 | struct GNUNET_DBUS_MethodContext * | ||
73 | GNUNET_DBUS_method_context_create ( | ||
74 | struct GNUNET_DBUS_Client *client, | ||
75 | struct GNUNET_DBUS_Service *service, | ||
76 | struct GNUNET_DBUS_Object *object, | ||
77 | struct GNUNET_DBUS_Interface *interface, | ||
78 | struct GNUNET_DBUS_Method *method, | ||
79 | DBusMessage *message); | ||
80 | |||
81 | /** | ||
82 | * Increase the reference count of this GNUNET_DBUS_MethodContext by one. | ||
83 | */ | ||
84 | void | ||
85 | GNUNET_DBUS_method_context_ref ( | ||
86 | struct GNUNET_DBUS_MethodContext *mc); | ||
87 | |||
88 | /** | ||
89 | * Decrease the reference count of this GNUNET_DBUS_MethodContext by one. Will | ||
90 | * free the method context if the reference count reaches zero. | ||
91 | */ | ||
92 | void | ||
93 | GNUNET_DBUS_method_context_unref ( | ||
94 | struct GNUNET_DBUS_MethodContext *mc); | ||
95 | |||
96 | /** | ||
97 | * Send a DBusMessage in reply to the method call associated with this method | ||
98 | * context. The DBusMessage should have been created using | ||
99 | * GNUNET_DBUS_method_context_create_reply. | ||
100 | */ | ||
101 | void | ||
102 | GNUNET_DBUS_method_context_send_reply ( | ||
103 | struct GNUNET_DBUS_MethodContext *mc, | ||
104 | DBusMessage *reply); | ||
105 | |||
106 | /** | ||
107 | * Create a DBusMessage in reply to this method call. After populating the | ||
108 | * message with data, send it using GNUNET_DBUS_method_context_send_reply. | ||
109 | */ | ||
110 | DBusMessage * | ||
111 | GNUNET_DBUS_method_context_create_reply ( | ||
112 | struct GNUNET_DBUS_MethodContext *mc); | ||
113 | |||
114 | #endif | ||
115 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_object.h b/src/lib/include/gnunet_dbus_lib_object.h new file mode 100644 index 0000000..3264494 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_object.h | |||
@@ -0,0 +1,125 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_OBJECT_H | ||
2 | #define GNUNET_DBUS_LIB_OBJECT_H | ||
3 | |||
4 | /** | ||
5 | * Represents a DBus object advertised on a DBus service. Objects are named and | ||
6 | * exist in a tree. For example, the object at the path | ||
7 | * /org/freedesktop/PolicyKit1/Authority is named Authority and sits in a | ||
8 | * heirarchy below four other objects including the service's root object. Each | ||
9 | * object has a set of interfaces and can be associated with an arbitrary piece | ||
10 | * of data. | ||
11 | */ | ||
12 | struct GNUNET_DBUS_Object; | ||
13 | |||
14 | #include "gnunet_dbus_lib_interface.h" | ||
15 | |||
16 | /** | ||
17 | * An iterable, doubly-linked-list of GNUNET_DBUS_Object. | ||
18 | */ | ||
19 | struct GNUNET_DBUS_ObjectIterator | ||
20 | { | ||
21 | /* linked list */ | ||
22 | struct GNUNET_DBUS_ObjectIterator *next; | ||
23 | struct GNUNET_DBUS_ObjectIterator *prev; | ||
24 | |||
25 | struct GNUNET_DBUS_Object *object; | ||
26 | }; | ||
27 | |||
28 | /** | ||
29 | * Create a new GNUNET_DBUS_Object with the given name and associated data. For | ||
30 | * example, the object that exists at the path | ||
31 | * /org/freedesktop/PolicyKit1/Authority has the name Authority and sits below | ||
32 | * four other objects including the service's root object. | ||
33 | */ | ||
34 | struct GNUNET_DBUS_Object * | ||
35 | GNUNET_DBUS_object_create ( | ||
36 | const char *name, | ||
37 | void *data); | ||
38 | |||
39 | /** | ||
40 | * Increase the reference count of this GNUNET_DBUS_Object by one. | ||
41 | */ | ||
42 | void | ||
43 | GNUNET_DBUS_object_ref ( | ||
44 | struct GNUNET_DBUS_Object *object); | ||
45 | |||
46 | /** | ||
47 | * Decrease the reference count of this GNUNET_DBUS_Object by one. Will free | ||
48 | * the GNUNET_DBUS_Object if the reference count reaches zero. | ||
49 | */ | ||
50 | void | ||
51 | GNUNET_DBUS_object_unref ( | ||
52 | struct GNUNET_DBUS_Object *object); | ||
53 | |||
54 | /** | ||
55 | * Get the name of this GNUNET_DBUS_Object. | ||
56 | */ | ||
57 | const char * | ||
58 | GNUNET_DBUS_object_get_name ( | ||
59 | const struct GNUNET_DBUS_Object *object); | ||
60 | |||
61 | /** | ||
62 | * Add an interface to this GNUNET_DBUS_Object. | ||
63 | */ | ||
64 | void | ||
65 | GNUNET_DBUS_object_add_interface ( | ||
66 | struct GNUNET_DBUS_Object *object, | ||
67 | struct GNUNET_DBUS_Interface *interface); | ||
68 | |||
69 | /** | ||
70 | * Iterate over the interfaces of this GNUNET_DBUS_Object. | ||
71 | */ | ||
72 | const struct GNUNET_DBUS_InterfaceIterator * | ||
73 | GNUNET_DBUS_object_iterate_interfaces ( | ||
74 | struct GNUNET_DBUS_Object *object); | ||
75 | |||
76 | /** | ||
77 | * Get the data associated with this GNUNET_DBUS_Object. | ||
78 | */ | ||
79 | void * | ||
80 | GNUNET_DBUS_object_get_data ( | ||
81 | struct GNUNET_DBUS_Object *object); | ||
82 | |||
83 | /** | ||
84 | * Create an object with a randomly generated name, associate data with it, and | ||
85 | * add it as a child to the given object. Returns the newly created object. | ||
86 | */ | ||
87 | struct GNUNET_DBUS_Object * | ||
88 | GNUNET_DBUS_object_create_uniquely_named_subobject ( | ||
89 | struct GNUNET_DBUS_Object *object, | ||
90 | void *data); | ||
91 | |||
92 | /** | ||
93 | * Add subobject as a child of object. | ||
94 | */ | ||
95 | void | ||
96 | GNUNET_DBUS_object_add_subobject ( | ||
97 | struct GNUNET_DBUS_Object *object, | ||
98 | struct GNUNET_DBUS_Object *subobject); | ||
99 | |||
100 | /** | ||
101 | * Remove the object pointed to by subobject_it as a child from object. | ||
102 | */ | ||
103 | void | ||
104 | GNUNET_DBUS_object_remove_subobject ( | ||
105 | struct GNUNET_DBUS_Object *object, | ||
106 | struct GNUNET_DBUS_ObjectIterator *subobject_it); | ||
107 | |||
108 | /** | ||
109 | * Iterate over an object's child objects. | ||
110 | */ | ||
111 | struct GNUNET_DBUS_ObjectIterator * | ||
112 | GNUNET_DBUS_object_iterate_subobjects ( | ||
113 | const struct GNUNET_DBUS_Object *object); | ||
114 | |||
115 | /** | ||
116 | * Search the given linked list of GNUNET_DBUS_Object for an object with the | ||
117 | * given name and return an iterator to it. | ||
118 | */ | ||
119 | const struct GNUNET_DBUS_ObjectIterator * | ||
120 | GNUNET_DBUS_object_find ( | ||
121 | const struct GNUNET_DBUS_ObjectIterator *object_it, | ||
122 | const char *name); | ||
123 | |||
124 | #endif | ||
125 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_object_path.h b/src/lib/include/gnunet_dbus_lib_object_path.h new file mode 100644 index 0000000..ec93d99 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_object_path.h | |||
@@ -0,0 +1,62 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_OBJECT_PATH_H | ||
2 | #define GNUNET_DBUS_LIB_OBJECT_PATH_H | ||
3 | |||
4 | #include "gnunet_dbus_lib_object.h" | ||
5 | |||
6 | /** | ||
7 | * Represents a path of DBus objects in service's object namespace. eg. | ||
8 | * /org/freedesktop/PolicyKit1/Authority | ||
9 | */ | ||
10 | struct GNUNET_DBUS_ObjectPath; | ||
11 | |||
12 | /** | ||
13 | * Create an object path from a GNUNET_DBUS_Service and a list of | ||
14 | * GNUNET_DBUS_Object. The last item in the list must be NULL. | ||
15 | * For example, to create the path to the | ||
16 | * /org/freedesktop/PolicyKit1/Authority1 object you would call as: | ||
17 | * | ||
18 | * GNUNET_DBUS_object_path_create(policy_kit_service_object, | ||
19 | * org_object, | ||
20 | * freedesktop_object, | ||
21 | * PolicyKit1_object, | ||
22 | * Authority_object, | ||
23 | * NULL); | ||
24 | */ | ||
25 | struct GNUNET_DBUS_ObjectPath * | ||
26 | GNUNET_DBUS_object_path_create ( | ||
27 | struct GNUNET_DBUS_Service *service, | ||
28 | ...) | ||
29 | __attribute__((sentinel)); | ||
30 | |||
31 | /** | ||
32 | * Increase the reference count of this GNUNET_DBUS_ObjectPath by one. | ||
33 | */ | ||
34 | void | ||
35 | GNUNET_DBUS_object_path_ref ( | ||
36 | struct GNUNET_DBUS_ObjectPath *path); | ||
37 | |||
38 | /** | ||
39 | * Decrease the reference count of this GNUNET_DBUS_ObjectPath by one. Will | ||
40 | * free the GNUNET_DBUS_ObjectPath if the reference count reaches zero. | ||
41 | */ | ||
42 | void | ||
43 | GNUNET_DBUS_object_path_unref ( | ||
44 | struct GNUNET_DBUS_ObjectPath *path); | ||
45 | |||
46 | /** | ||
47 | * Format the GNUNET_DBUS_ObjectPath as a string. eg. | ||
48 | * "/org/freedesktop/PolicyKit1/Authority1". | ||
49 | */ | ||
50 | char * | ||
51 | GNUNET_DBUS_object_path_to_string ( | ||
52 | const struct GNUNET_DBUS_ObjectPath *path); | ||
53 | |||
54 | /** | ||
55 | * Get the destination object of this path. ie. the final object in the path. | ||
56 | */ | ||
57 | struct GNUNET_DBUS_Object * | ||
58 | GNUNET_DBUS_object_path_get_destination ( | ||
59 | const struct GNUNET_DBUS_ObjectPath *path); | ||
60 | |||
61 | #endif | ||
62 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_pop.h b/src/lib/include/gnunet_dbus_lib_pop.h new file mode 100644 index 0000000..6ffde70 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_pop.h | |||
@@ -0,0 +1,408 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_POP_H | ||
2 | #define GNUNET_DBUS_LIB_POP_H | ||
3 | |||
4 | /** | ||
5 | * Pop a byte from a DBus message, advancing the iterator. `arg_name` is used | ||
6 | * for reporting useful diagnostics if the value in the message is missing or | ||
7 | * the wrong type. | ||
8 | */ | ||
9 | DBusMessage * | ||
10 | GNUNET_DBUS_pop_byte ( | ||
11 | DBusMessage *message, | ||
12 | DBusMessageIter *iter, | ||
13 | const char *arg_name, | ||
14 | unsigned char *value); | ||
15 | |||
16 | /** | ||
17 | * Pop a boolean from a DBus message, advancing the iterator. `arg_name` is | ||
18 | * used for reporting useful diagnostics if the value in the message is missing | ||
19 | * or the wrong type. | ||
20 | */ | ||
21 | DBusMessage * | ||
22 | GNUNET_DBUS_pop_boolean ( | ||
23 | DBusMessage *message, | ||
24 | DBusMessageIter *iter, | ||
25 | const char *arg_name, | ||
26 | dbus_bool_t *value); | ||
27 | |||
28 | /** | ||
29 | * Pop an int16 from a DBus message, advancing the iterator. `arg_name` is used | ||
30 | * for reporting useful diagnostics if the value in the message is missing or | ||
31 | * the wrong type. | ||
32 | */ | ||
33 | DBusMessage * | ||
34 | GNUNET_DBUS_pop_int16 ( | ||
35 | DBusMessage *message, | ||
36 | DBusMessageIter *iter, | ||
37 | const char *arg_name, | ||
38 | dbus_int16_t *value); | ||
39 | |||
40 | /** | ||
41 | * Pop a uint16 from a DBus message, advancing the iterator. `arg_name` is used | ||
42 | * for reporting useful diagnostics if the value in the message is missing or | ||
43 | * the wrong type. | ||
44 | */ | ||
45 | DBusMessage * | ||
46 | GNUNET_DBUS_pop_uint16 ( | ||
47 | DBusMessage *message, | ||
48 | DBusMessageIter *iter, | ||
49 | const char *arg_name, | ||
50 | dbus_uint16_t *value); | ||
51 | |||
52 | /** | ||
53 | * Pop an int32 from a DBus message, advancing the iterator. `arg_name` is | ||
54 | * used for reporting useful diagnostics if the value in the message is missing | ||
55 | * or the wrong type. | ||
56 | */ | ||
57 | DBusMessage * | ||
58 | GNUNET_DBUS_pop_int32 ( | ||
59 | DBusMessage *message, | ||
60 | DBusMessageIter *iter, | ||
61 | const char *arg_name, | ||
62 | dbus_int32_t *value); | ||
63 | |||
64 | /** | ||
65 | * Pop a uint32 from a DBus message, advancing the iterator. `arg_name` is | ||
66 | * used for reporting useful diagnostics if the value in the message is missing | ||
67 | * or the wrong type. | ||
68 | */ | ||
69 | DBusMessage * | ||
70 | GNUNET_DBUS_pop_uint32 ( | ||
71 | DBusMessage *message, | ||
72 | DBusMessageIter *iter, | ||
73 | const char *arg_name, | ||
74 | dbus_uint32_t *value); | ||
75 | |||
76 | /** | ||
77 | * Pop an int64 from a DBus message, advancing the iterator. `arg_name` is | ||
78 | * used for reporting useful diagnostics if the value in the message is missing | ||
79 | * or the wrong type. | ||
80 | */ | ||
81 | DBusMessage * | ||
82 | GNUNET_DBUS_pop_int64 ( | ||
83 | DBusMessage *message, | ||
84 | DBusMessageIter *iter, | ||
85 | const char *arg_name, | ||
86 | dbus_int64_t *value); | ||
87 | |||
88 | /** | ||
89 | * Pop a uint64 from a DBus message, advancing the iterator. `arg_name` is | ||
90 | * used for reporting useful diagnostics if the value in the message is missing | ||
91 | * or the wrong type. | ||
92 | */ | ||
93 | DBusMessage * | ||
94 | GNUNET_DBUS_pop_uint64 ( | ||
95 | DBusMessage *message, | ||
96 | DBusMessageIter *iter, | ||
97 | const char *arg_name, | ||
98 | dbus_uint64_t *value); | ||
99 | |||
100 | /** | ||
101 | * Pop a double from a DBus message, advancing the iterator. `arg_name` is used | ||
102 | * for reporting useful diagnostics if the value in the message is missing or | ||
103 | * the wrong type. | ||
104 | */ | ||
105 | DBusMessage * | ||
106 | GNUNET_DBUS_pop_double ( | ||
107 | DBusMessage *message, | ||
108 | DBusMessageIter *iter, | ||
109 | const char *arg_name, | ||
110 | double *value); | ||
111 | |||
112 | /** | ||
113 | * Pop a string from a DBus message, advancing the iterator. `arg_name` is used | ||
114 | * for reporting useful diagnostics if the value in the message is missing or | ||
115 | * the wrong type. | ||
116 | */ | ||
117 | DBusMessage * | ||
118 | GNUNET_DBUS_pop_string ( | ||
119 | DBusMessage *message, | ||
120 | DBusMessageIter *iter, | ||
121 | const char *arg_name, | ||
122 | const char **value); | ||
123 | |||
124 | /** | ||
125 | * Pop a DBus object path from a DBus message, advancing the iterator. The | ||
126 | * object path is returned in *value as a string. `arg_name` is used for | ||
127 | * reporting useful diagnostics if the value in the message is missing or the | ||
128 | * wrong type. | ||
129 | */ | ||
130 | DBusMessage * | ||
131 | GNUNET_DBUS_pop_object_path ( | ||
132 | DBusMessage *message, | ||
133 | DBusMessageIter *iter, | ||
134 | const char *arg_name, | ||
135 | const char **value); | ||
136 | |||
137 | /** | ||
138 | * Pop a DBus type signature from a DBusMessage, advancing the iterator. The | ||
139 | * type signature is returned in *value as a string. `arg_name` is used for | ||
140 | * reporting useful diagnostics if the value in the message is missing or the | ||
141 | * wrong type. | ||
142 | */ | ||
143 | DBusMessage * | ||
144 | GNUNET_DBUS_pop_signature ( | ||
145 | DBusMessage *message, | ||
146 | DBusMessageIter *iter, | ||
147 | const char *arg_name, | ||
148 | const char **value); | ||
149 | |||
150 | /** | ||
151 | * Pop a unix file descriptor from a DBusMessage, advancing the iterator. | ||
152 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
153 | * message is missing or the wrong type. | ||
154 | */ | ||
155 | DBusMessage * | ||
156 | GNUNET_DBUS_pop_unix_fd ( | ||
157 | DBusMessage *message, | ||
158 | DBusMessageIter *iter, | ||
159 | const char *arg_name, | ||
160 | int *value); | ||
161 | |||
162 | /** | ||
163 | * Pop an array from a DBusMessage. Moves iter past the array and initialises | ||
164 | * iter_sub to point to the first element of the array. The length of the array | ||
165 | * is returned in *len. `arg_name` is used for reporting useful diagnostics if | ||
166 | * the value in the message is missing or the wrong type. | ||
167 | */ | ||
168 | DBusMessage * | ||
169 | GNUNET_DBUS_pop_enter_array ( | ||
170 | DBusMessage *message, | ||
171 | DBusMessageIter *iter, | ||
172 | DBusMessageIter *iter_sub, | ||
173 | const char *arg_name, | ||
174 | size_t *len); | ||
175 | |||
176 | /** | ||
177 | * Pop a struct from a DBusMessage. Moves iter past the struct and initialises | ||
178 | * iter_sub to point to the first element of the struct. `arg_name` is used for | ||
179 | * reporting useful diagnostics if the value in the message is missing or the | ||
180 | * wrong type. | ||
181 | */ | ||
182 | DBusMessage * | ||
183 | GNUNET_DBUS_pop_enter_struct ( | ||
184 | DBusMessage *message, | ||
185 | DBusMessageIter *iter, | ||
186 | DBusMessageIter *iter_sub, | ||
187 | const char *arg_name); | ||
188 | |||
189 | /** | ||
190 | * Pop a variant from a DBusMessage. Moves iter past the variant and | ||
191 | * initialises iter_sub to point to the value inside the variant. `arg_name` | ||
192 | * is used for reporting useful diagnostics if the value in the message is | ||
193 | * missing or the wrong type. | ||
194 | */ | ||
195 | DBusMessage * | ||
196 | GNUNET_DBUS_pop_enter_variant ( | ||
197 | DBusMessage *message, | ||
198 | DBusMessageIter *iter, | ||
199 | DBusMessageIter *iter_sub, | ||
200 | const char *arg_name); | ||
201 | |||
202 | /** | ||
203 | * Pop a dictionary entry from a DBusMessage. Moves iter past the dictionary | ||
204 | * entry and initialises iter_sub to point to the key. The key and value can | ||
205 | * then be popped in sequence using iter_sub. `arg_name` is used for reporting | ||
206 | * useful diagnostics if the value in the message is missing or the wrong type. | ||
207 | */ | ||
208 | DBusMessage * | ||
209 | GNUNET_DBUS_pop_enter_dict_entry ( | ||
210 | DBusMessage *message, | ||
211 | DBusMessageIter *iter, | ||
212 | DBusMessageIter *iter_sub, | ||
213 | const char *arg_name); | ||
214 | |||
215 | /** | ||
216 | * Pop an array of bytes from a DBusMessage. A pointer to the array is stored | ||
217 | * in *value. The array is not copied so *value will become invalid once the | ||
218 | * message has been freed. The length of the array is stored in *n_elements. | ||
219 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
220 | * message is missing or the wrong type. | ||
221 | */ | ||
222 | DBusMessage * | ||
223 | GNUNET_DBUS_pop_byte_array ( | ||
224 | DBusMessage *message, | ||
225 | DBusMessageIter *iter, | ||
226 | const char *arg_name, | ||
227 | const unsigned char **value, | ||
228 | int *n_elements); | ||
229 | |||
230 | /** | ||
231 | * Pop an array of booleans from a DBusMessage. A pointer to the array is | ||
232 | * stored in *value. The array is not copied so *value will become invalid once | ||
233 | * the message has been freed. The length of the array is stored in | ||
234 | * *n_elements. `arg_name` is used for reporting useful diagnostics if the | ||
235 | * value in the message is missing or the wrong type. | ||
236 | */ | ||
237 | DBusMessage * | ||
238 | GNUNET_DBUS_pop_boolean_array ( | ||
239 | DBusMessage *message, | ||
240 | DBusMessageIter *iter, | ||
241 | const char *arg_name, | ||
242 | const dbus_bool_t **value, | ||
243 | int *n_elements); | ||
244 | |||
245 | /** | ||
246 | * Pop an array of int16s from a DBusMessage. A pointer to the array is stored | ||
247 | * in *value. The array is not copied so *value will become invalid once the | ||
248 | * message has been freed. The length of the array is stored in *n_elements. | ||
249 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
250 | * message is missing or the wrong type. | ||
251 | */ | ||
252 | DBusMessage * | ||
253 | GNUNET_DBUS_pop_int16_array ( | ||
254 | DBusMessage *message, | ||
255 | DBusMessageIter *iter, | ||
256 | const char *arg_name, | ||
257 | const int16_t **value, | ||
258 | int *n_elements); | ||
259 | |||
260 | /** | ||
261 | * Pop an array of uint16s from a DBusMessage. A pointer to the array is stored | ||
262 | * in *value. The array is not copied so *value will become invalid once the | ||
263 | * message has been freed. The length of the array is stored in *n_elements. | ||
264 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
265 | * message is missing or the wrong type. | ||
266 | */ | ||
267 | DBusMessage * | ||
268 | GNUNET_DBUS_pop_uint16_array ( | ||
269 | DBusMessage *message, | ||
270 | DBusMessageIter *iter, | ||
271 | const char *arg_name, | ||
272 | const uint16_t **value, | ||
273 | int *n_elements); | ||
274 | |||
275 | /** | ||
276 | * Pop an array of int32s from a DBusMessage. A pointer to the array is stored | ||
277 | * in *value. The array is not copied so *value will become invalid once the | ||
278 | * message has been freed. The length of the array is stored in *n_elements. | ||
279 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
280 | * message is missing or the wrong type. | ||
281 | */ | ||
282 | DBusMessage * | ||
283 | GNUNET_DBUS_pop_int32_array ( | ||
284 | DBusMessage *message, | ||
285 | DBusMessageIter *iter, | ||
286 | const char *arg_name, | ||
287 | const int32_t **value, | ||
288 | int *n_elements); | ||
289 | |||
290 | /** | ||
291 | * Pop an array of uint32s from a DBusMessage. A pointer to the array is stored | ||
292 | * in *value. The array is not copied so *value will become invalid once the | ||
293 | * message has been freed. The length of the array is stored in *n_elements. | ||
294 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
295 | * message is missing or the wrong type. | ||
296 | */ | ||
297 | DBusMessage * | ||
298 | GNUNET_DBUS_pop_uint32_array ( | ||
299 | DBusMessage *message, | ||
300 | DBusMessageIter *iter, | ||
301 | const char *arg_name, | ||
302 | const uint32_t **value, | ||
303 | int *n_elements); | ||
304 | |||
305 | /** | ||
306 | * Pop an array of int64s from a DBusMessage. A pointer to the array is stored | ||
307 | * in *value. The array is not copied so *value will become invalid once the | ||
308 | * message has been freed. The length of the array is stored in *n_elements. | ||
309 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
310 | * message is missing or the wrong type. | ||
311 | */ | ||
312 | DBusMessage * | ||
313 | GNUNET_DBUS_pop_int64_array ( | ||
314 | DBusMessage *message, | ||
315 | DBusMessageIter *iter, | ||
316 | const char *arg_name, | ||
317 | const int64_t **value, | ||
318 | int *n_elements); | ||
319 | |||
320 | /** | ||
321 | * Pop an array of uint64s from a DBusMessage. A pointer to the array is stored | ||
322 | * in *value. The array is not copied so *value will become invalid once the | ||
323 | * message has been freed. The length of the array is stored in *n_elements. | ||
324 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
325 | * message is missing or the wrong type. | ||
326 | */ | ||
327 | DBusMessage * | ||
328 | GNUNET_DBUS_pop_uint64_array ( | ||
329 | DBusMessage *message, | ||
330 | DBusMessageIter *iter, | ||
331 | const char *arg_name, | ||
332 | const uint64_t **value, | ||
333 | int *n_elements); | ||
334 | |||
335 | /* | ||
336 | * Pop a bitfield enum from a DBusMessage, advancing the iterator. A bitfield | ||
337 | * enum is an enum where the individual bits represent different flags. See for | ||
338 | * example the definition of GNUNET_GNSRECORD_Flags: | ||
339 | * | ||
340 | * enum GNUNET_GNSRECORD_Flags { | ||
341 | * GNUNET_GNSRECORD_RF_PRIVATE = 2, | ||
342 | * // GNUNET_GNSRECORD_RF_UNUSED = 4, | ||
343 | * GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 8, | ||
344 | * GNUNET_GNSRECORD_RF_SHADOW_RECORD = 16 | ||
345 | * } | ||
346 | * | ||
347 | * Bitfield enums can be sent across the wire in either their integer form (as | ||
348 | * a uint32) or as an array of strings. Sending an int is more efficient and is | ||
349 | * what libraries built around the DBus API would use. People using the DBus | ||
350 | * API directly via the command line or a DBus debugger may want to pass | ||
351 | * human-readable strings for convenience. names is a pointer to a | ||
352 | * {NULL, 0}-terminated array of GNUNET_DBUS_StringEnumPair which assigns | ||
353 | * human-readable names to the bitfields. `arg_name` is used for reporting | ||
354 | * useful diagnostics if the value in the message is missing or the wrong type. | ||
355 | */ | ||
356 | DBusMessage * | ||
357 | GNUNET_DBUS_pop_bitfield ( | ||
358 | DBusMessage *message, | ||
359 | DBusMessageIter *iter, | ||
360 | const char *arg_name, | ||
361 | int *value, | ||
362 | const struct GNUNET_DBUS_StringEnumPair *fields); | ||
363 | |||
364 | /** | ||
365 | * Pop an enum from a DBusMessage, advancing the iterator. enums can be sent | ||
366 | * across the wire as either a uint32 or as a string. Sending a uint32 is more | ||
367 | * efficient and is what libraries built around the DBus API would use. People | ||
368 | * using the DBus API directly via the command line or a DBus debugger may want | ||
369 | * to pass human-readable strings for convenience. names is a pointer to a | ||
370 | * {NULL, 0}-terminated array of GNUNET_DBUS_StringEnumPair which assigns | ||
371 | * human-readable names to the different enum variants. `arg_name` is used for | ||
372 | * reporting useful diagnostics if the value in the message is missing or the | ||
373 | * wrong type. | ||
374 | */ | ||
375 | DBusMessage * | ||
376 | GNUNET_DBUS_pop_enum ( | ||
377 | DBusMessage *message, | ||
378 | DBusMessageIter *iter, | ||
379 | const char *arg_name, | ||
380 | int *value, | ||
381 | const struct GNUNET_DBUS_StringEnumPair *names); | ||
382 | |||
383 | /** | ||
384 | * Pop a GNUNET_HashCode from a DBusMessage, advancing the iterator. | ||
385 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
386 | * message is missing or the wrong type. | ||
387 | */ | ||
388 | DBusMessage * | ||
389 | GNUNET_DBUS_pop_hashcode ( | ||
390 | DBusMessage *message, | ||
391 | DBusMessageIter *iter, | ||
392 | const char *arg_name, | ||
393 | struct GNUNET_HashCode *value); | ||
394 | |||
395 | /** | ||
396 | * Pop a GNUNET_PeerIdentity from a DBusMessage, advancing the iterator. | ||
397 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
398 | * message is missing or the wrong type. | ||
399 | */ | ||
400 | DBusMessage * | ||
401 | GNUNET_DBUS_pop_peer_identity ( | ||
402 | DBusMessage *message, | ||
403 | DBusMessageIter *iter, | ||
404 | const char *arg_name, | ||
405 | struct GNUNET_PeerIdentity *value); | ||
406 | |||
407 | #endif | ||
408 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_push.h b/src/lib/include/gnunet_dbus_lib_push.h new file mode 100644 index 0000000..31a9bc9 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_push.h | |||
@@ -0,0 +1,397 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_PUSH_H | ||
2 | #define GNUNET_DBUS_LIB_PUSH_H | ||
3 | |||
4 | #include <dbus/dbus.h> | ||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_crypto_lib.h> | ||
8 | |||
9 | /** | ||
10 | * Push a byte to a DBus message, advancing the iterator. | ||
11 | */ | ||
12 | void | ||
13 | GNUNET_DBUS_push_byte ( | ||
14 | DBusMessage *message, | ||
15 | DBusMessageIter *iter, | ||
16 | const unsigned char *value); | ||
17 | |||
18 | /** | ||
19 | * Push a boolean to a DBus message, advancing the iterator. | ||
20 | */ | ||
21 | void | ||
22 | GNUNET_DBUS_push_boolean ( | ||
23 | DBusMessage *message, | ||
24 | DBusMessageIter *iter, | ||
25 | const dbus_bool_t *value); | ||
26 | |||
27 | /** | ||
28 | * Push an int16 to a DBus message, advancing the iterator. | ||
29 | */ | ||
30 | void | ||
31 | GNUNET_DBUS_push_int16 ( | ||
32 | DBusMessage *message, | ||
33 | DBusMessageIter *iter, | ||
34 | const dbus_int16_t *value); | ||
35 | |||
36 | /** | ||
37 | * Push a uint16 to a DBus message, advancing the iterator. | ||
38 | */ | ||
39 | void | ||
40 | GNUNET_DBUS_push_uint16 ( | ||
41 | DBusMessage *message, | ||
42 | DBusMessageIter *iter, | ||
43 | const dbus_uint16_t *value); | ||
44 | |||
45 | /** | ||
46 | * Push an int32 to a DBus message, advancing the iterator. | ||
47 | */ | ||
48 | void | ||
49 | GNUNET_DBUS_push_int32 ( | ||
50 | DBusMessage *message, | ||
51 | DBusMessageIter *iter, | ||
52 | const dbus_int32_t *value); | ||
53 | |||
54 | /** | ||
55 | * Push a uint32 to a DBus message, advancing the iterator. | ||
56 | */ | ||
57 | void | ||
58 | GNUNET_DBUS_push_uint32 ( | ||
59 | DBusMessage *message, | ||
60 | DBusMessageIter *iter, | ||
61 | const dbus_uint32_t *value); | ||
62 | |||
63 | /** | ||
64 | * Push an int64 to a DBus message, advancing the iterator. | ||
65 | */ | ||
66 | void | ||
67 | GNUNET_DBUS_push_int64 ( | ||
68 | DBusMessage *message, | ||
69 | DBusMessageIter *iter, | ||
70 | const dbus_int64_t *value); | ||
71 | |||
72 | /** | ||
73 | * Push a uint64 to a DBus message, advancing the iterator. | ||
74 | */ | ||
75 | void | ||
76 | GNUNET_DBUS_push_uint64 ( | ||
77 | DBusMessage *message, | ||
78 | DBusMessageIter *iter, | ||
79 | const dbus_uint64_t *value); | ||
80 | |||
81 | /** | ||
82 | * Push a double to a DBus message, advancing the iterator. | ||
83 | */ | ||
84 | void | ||
85 | GNUNET_DBUS_push_double ( | ||
86 | DBusMessage *message, | ||
87 | DBusMessageIter *iter, | ||
88 | const double *value); | ||
89 | |||
90 | /** | ||
91 | * Push a string to a DBus message, advancing the iterator. | ||
92 | */ | ||
93 | void | ||
94 | GNUNET_DBUS_push_string ( | ||
95 | DBusMessage *message, | ||
96 | DBusMessageIter *iter, | ||
97 | const char *const *value); | ||
98 | |||
99 | /** | ||
100 | * Push an object path to a DBus message, advancing the iterator. | ||
101 | */ | ||
102 | void | ||
103 | GNUNET_DBUS_push_object_path ( | ||
104 | DBusMessage *message, | ||
105 | DBusMessageIter *iter, | ||
106 | const struct GNUNET_DBUS_ObjectPath *path); | ||
107 | |||
108 | /** | ||
109 | * Push a DBus type signature to a DBus message, advancing the iterator. | ||
110 | */ | ||
111 | void | ||
112 | GNUNET_DBUS_push_signature ( | ||
113 | DBusMessage *message, | ||
114 | DBusMessageIter *iter, | ||
115 | const char *const *value); | ||
116 | |||
117 | /** | ||
118 | * Push a unix file descriptor to a DBus message, advancing the iterator. | ||
119 | */ | ||
120 | void | ||
121 | GNUNET_DBUS_push_unix_fd ( | ||
122 | DBusMessage *message, | ||
123 | DBusMessageIter *iter, | ||
124 | const int *value); | ||
125 | |||
126 | /** | ||
127 | * Push a unix file descriptor to a DBus message, advancing the iterator. | ||
128 | */ | ||
129 | void | ||
130 | GNUNET_DBUS_push_open_array ( | ||
131 | DBusMessage *message, | ||
132 | DBusMessageIter *iter, | ||
133 | DBusMessageIter *iter_sub, | ||
134 | const char *signature); | ||
135 | |||
136 | /** | ||
137 | * Commence pushing an array to a DBusMessage. iter_sub is initialised to point | ||
138 | * to the start of a new array and can be used to populate the array. | ||
139 | * GNUNET_DBUS_push_close_array must be called after the array has been | ||
140 | * populated. iter is invalid until GNUNET_DBUS_push_close_array has been called. | ||
141 | */ | ||
142 | void | ||
143 | GNUNET_DBUS_push_open_struct ( | ||
144 | DBusMessage *message, | ||
145 | DBusMessageIter *iter, | ||
146 | DBusMessageIter *iter_sub); | ||
147 | |||
148 | /** | ||
149 | * Commence pushing a variant to a DBusMessage. iter_sub is initialised to | ||
150 | * point to an empty variant and must be used to place the value in the | ||
151 | * variant. After the value is placed, GNUNET_DBUS_push_close_variant must be | ||
152 | * called. iter is invalid until GNUNET_DBUS_push_close_array has been called. | ||
153 | */ | ||
154 | void | ||
155 | GNUNET_DBUS_push_open_variant ( | ||
156 | DBusMessage *message, | ||
157 | DBusMessageIter *iter, | ||
158 | DBusMessageIter *iter_sub, | ||
159 | const char *signature); | ||
160 | |||
161 | /** | ||
162 | * Commence pushing a dictionary entry onto a DBusMessage. iter_sub is | ||
163 | * initialised to point to the start of the new dictionary entry. It must be | ||
164 | * used to push the key and value in order after which | ||
165 | * GNUNET_DBUS_push_close_dict_entry must be called. iter is invalid until | ||
166 | * GNUNET_DBUS_push_close_array has been called. | ||
167 | */ | ||
168 | void | ||
169 | GNUNET_DBUS_push_open_dict_entry ( | ||
170 | DBusMessage *message, | ||
171 | DBusMessageIter *iter, | ||
172 | DBusMessageIter *iter_sub); | ||
173 | |||
174 | /** | ||
175 | * Finish pushing an array to a DBusMesage. This must be called after | ||
176 | * GNUNET_DBUS_push_open_array and after the array elements have been pushed to | ||
177 | * the message. After calling this function, iter_sub becomes invalid and iter | ||
178 | * can again be used to push data to the message. | ||
179 | */ | ||
180 | void | ||
181 | GNUNET_DBUS_push_close_array ( | ||
182 | DBusMessage *message, | ||
183 | DBusMessageIter *iter, | ||
184 | DBusMessageIter *iter_sub); | ||
185 | |||
186 | /** | ||
187 | * Finish pushing a struct to a DBusMessage. This must be called after | ||
188 | * GNUNET_DBUS_push_open_struct and after the struct members have been pushed | ||
189 | * to the message. iter is invalid until GNUNET_DBUS_push_close_array has been | ||
190 | * called. After calling this function, iter_sub becomes invalid and iter can | ||
191 | * again be used to push data to the message. | ||
192 | */ | ||
193 | void | ||
194 | GNUNET_DBUS_push_close_struct ( | ||
195 | DBusMessage *message, | ||
196 | DBusMessageIter *iter, | ||
197 | DBusMessageIter *iter_sub); | ||
198 | |||
199 | /** | ||
200 | * Finish pushing a variant to a DBusMessage. This must be called after | ||
201 | * GNUNET_DBUS_push_open_variant and after the variant's value has been pushed | ||
202 | * to the message. After calling this function, iter_sub becomes invalid and | ||
203 | * iter can again be used to push data to the message. | ||
204 | */ | ||
205 | void | ||
206 | GNUNET_DBUS_push_close_variant ( | ||
207 | DBusMessage *message, | ||
208 | DBusMessageIter *iter, | ||
209 | DBusMessageIter *iter_sub); | ||
210 | |||
211 | /** | ||
212 | * Finish pushing a dictionary entry to a DBusMessage. This must be called | ||
213 | * after GNUNET_DBUS_push_open_dict_entry and after the key and value have been | ||
214 | * pushed to the message. After calling this function, iter_sub becomes invalid | ||
215 | * and iter can again be used to push data to the message. | ||
216 | */ | ||
217 | void | ||
218 | GNUNET_DBUS_push_close_dict_entry ( | ||
219 | DBusMessage *message, | ||
220 | DBusMessageIter *iter, | ||
221 | DBusMessageIter *iter_sub); | ||
222 | |||
223 | /** | ||
224 | * Push an array of bytes to a DBusMessage, advancing the iterator. The values | ||
225 | * are copied to the message. value_count is the number of elements in the array. | ||
226 | */ | ||
227 | void | ||
228 | GNUNET_DBUS_push_byte_array ( | ||
229 | DBusMessage *message, | ||
230 | DBusMessageIter *iter, | ||
231 | const unsigned char *value, | ||
232 | size_t value_count); | ||
233 | |||
234 | /** | ||
235 | * Push an array of booleans to a DBusMessage, advancing the iterator. The values | ||
236 | * are copied to the message. value_count is the number of elements in the array. | ||
237 | */ | ||
238 | void | ||
239 | GNUNET_DBUS_push_boolean_array ( | ||
240 | DBusMessage *message, | ||
241 | DBusMessageIter *iter, | ||
242 | const dbus_bool_t *value, | ||
243 | size_t value_count); | ||
244 | |||
245 | /** | ||
246 | * Push an array of int16s to a DBusMessage, advancing the iterator. The values | ||
247 | * are copied to the message. value_count is the number of elements in the array. | ||
248 | */ | ||
249 | void | ||
250 | GNUNET_DBUS_push_int16_array ( | ||
251 | DBusMessage *message, | ||
252 | DBusMessageIter *iter, | ||
253 | const dbus_int16_t *value, | ||
254 | size_t value_count); | ||
255 | |||
256 | /** | ||
257 | * Push an array of uint16s to a DBusMessage, advancing the iterator. The values | ||
258 | * are copied to the message. value_count is the number of elements in the array. | ||
259 | */ | ||
260 | void | ||
261 | GNUNET_DBUS_push_uint16_array ( | ||
262 | DBusMessage *message, | ||
263 | DBusMessageIter *iter, | ||
264 | const dbus_uint16_t *value, | ||
265 | size_t value_count); | ||
266 | |||
267 | /** | ||
268 | * Push an array of int32s to a DBusMessage, advancing the iterator. The values | ||
269 | * are copied to the message. value_count is the number of elements in the array. | ||
270 | */ | ||
271 | void | ||
272 | GNUNET_DBUS_push_int32_array ( | ||
273 | DBusMessage *message, | ||
274 | DBusMessageIter *iter, | ||
275 | const unsigned char *value, | ||
276 | size_t value_count); | ||
277 | |||
278 | /** | ||
279 | * Push an array of uint32s to a DBusMessage, advancing the iterator. The values | ||
280 | * are copied to the message. value_count is the number of elements in the array. | ||
281 | */ | ||
282 | void | ||
283 | GNUNET_DBUS_push_uint32_array ( | ||
284 | DBusMessage *message, | ||
285 | DBusMessageIter *iter, | ||
286 | const unsigned char *value, | ||
287 | size_t value_count); | ||
288 | |||
289 | /** | ||
290 | * Push an array of int64s to a DBusMessage, advancing the iterator. The values | ||
291 | * are copied to the message. value_count is the number of elements in the array. | ||
292 | */ | ||
293 | void | ||
294 | GNUNET_DBUS_push_int64_array ( | ||
295 | DBusMessage *message, | ||
296 | DBusMessageIter *iter, | ||
297 | const unsigned char *value, | ||
298 | size_t value_count); | ||
299 | |||
300 | /** | ||
301 | * Push an array of uint64s to a DBusMessage, advancing the iterator. The values | ||
302 | * are copied to the message. value_count is the number of elements in the array. | ||
303 | */ | ||
304 | void | ||
305 | GNUNET_DBUS_push_uint64_array ( | ||
306 | DBusMessage *message, | ||
307 | DBusMessageIter *iter, | ||
308 | const unsigned char *value, | ||
309 | size_t value_count); | ||
310 | |||
311 | /** | ||
312 | * Push an array of doubles to a DBusMessage, advancing the iterator. The values | ||
313 | * are copied to the message. value_count is the number of elements in the array. | ||
314 | */ | ||
315 | void | ||
316 | GNUNET_DBUS_push_double_array ( | ||
317 | DBusMessage *message, | ||
318 | DBusMessageIter *iter, | ||
319 | const unsigned char *value, | ||
320 | size_t value_count); | ||
321 | |||
322 | /** | ||
323 | * Push binary data to a DBusMessage, advancing the iterator. The data is | ||
324 | * copied to the message. value_count is the number of bytes of data. The data | ||
325 | * may be represented on-the-wire as either an array of bytes or a base32 | ||
326 | * encoded string depending on the pretty_encoding flag of the message. | ||
327 | */ | ||
328 | void | ||
329 | GNUNET_DBUS_push_data ( | ||
330 | DBusMessage *message, | ||
331 | DBusMessageIter *iter, | ||
332 | const void *value, | ||
333 | size_t value_size); | ||
334 | |||
335 | /* | ||
336 | * Push a bitfield enum to a DBusMessage, advancing the iterator. A bitfield | ||
337 | * enum is an enum where the individual bits represent different flags. See for | ||
338 | * example the definition of GNUNET_GNSRECORD_Flags: | ||
339 | * | ||
340 | * enum GNUNET_GNSRECORD_Flags { GNUNET_GNSRECORD_RF_PRIVATE = 2, // | ||
341 | * GNUNET_GNSRECORD_RF_UNUSED = 4, GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = | ||
342 | * 8, GNUNET_GNSRECORD_RF_SHADOW_RECORD = 16 } | ||
343 | * | ||
344 | * Bitfield enums can be sent across the wire in either their integer form (as | ||
345 | * a uint32) or as an array of strings depending on the pretty_encoding flag of | ||
346 | * the message. Sending an int is more efficient and is what libraries built | ||
347 | * around the DBus API would use. People using the DBus API directly via the | ||
348 | * command line or a DBus debugger may prefer to receive human-readable strings | ||
349 | * for convenience. names is a pointer to a {NULL, 0}-terminated array of | ||
350 | * GNUNET_DBUS_StringEnumPair which assigns human-readable names to the | ||
351 | * bitfields. | ||
352 | */ | ||
353 | void | ||
354 | GNUNET_DBUS_push_bitfield ( | ||
355 | DBusMessage *message, | ||
356 | DBusMessageIter *iter, | ||
357 | const int *value, | ||
358 | const struct GNUNET_DBUS_StringEnumPair *fields); | ||
359 | |||
360 | /** | ||
361 | * Push an enum to a DBusMessage, advancing the iterator. enums can be sent | ||
362 | * across the wire as either a uint32 or as a string depending on the | ||
363 | * pretty_encoding flag of the message. Sending a uint32 is more efficient and | ||
364 | * is what libraries built around the DBus API would use. People using the DBus | ||
365 | * API directly via the command line or a DBus debugger may prefer to receive | ||
366 | * human-readable strings for convenience. names is a pointer to a | ||
367 | * {NULL, 0}-terminated array of GNUNET_DBUS_StringEnumPair which assigns | ||
368 | * human-readable names to the different enum variants. | ||
369 | */ | ||
370 | void | ||
371 | GNUNET_DBUS_push_enum ( | ||
372 | DBusMessage *message, | ||
373 | DBusMessageIter *iter, | ||
374 | const int *value, | ||
375 | const struct GNUNET_DBUS_StringEnumPair *names); | ||
376 | |||
377 | /** | ||
378 | * Push a GNUNET_HashCode to a DBusMessage, advancing the iterator. | ||
379 | */ | ||
380 | void | ||
381 | GNUNET_DBUS_push_hashcode ( | ||
382 | DBusMessage *message, | ||
383 | DBusMessageIter *iter, | ||
384 | const struct GNUNET_HashCode *value); | ||
385 | |||
386 | /** | ||
387 | * Push a GNUNET_PeerIdentity to a DBusMessage, advancing the iterator. | ||
388 | */ | ||
389 | void | ||
390 | GNUNET_DBUS_push_peer_identity ( | ||
391 | DBusMessage *message, | ||
392 | DBusMessageIter *iter, | ||
393 | const struct GNUNET_PeerIdentity *value); | ||
394 | |||
395 | #endif | ||
396 | |||
397 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_service.h b/src/lib/include/gnunet_dbus_lib_service.h new file mode 100644 index 0000000..4d88079 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_service.h | |||
@@ -0,0 +1,87 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_SERVICE_H | ||
2 | #define GNUNET_DBUS_LIB_SERVICE_H | ||
3 | |||
4 | #include <gnunet/platform.h> | ||
5 | #include <gnunet/gnunet_common.h> | ||
6 | #include <gnunet/gnunet_configuration_lib.h> | ||
7 | |||
8 | /** | ||
9 | * Represents a DBus service that we are running. | ||
10 | */ | ||
11 | struct GNUNET_DBUS_Service; | ||
12 | |||
13 | #include "gnunet_dbus_lib_object.h" | ||
14 | #include "gnunet_dbus_lib_client.h" | ||
15 | |||
16 | /** | ||
17 | * The type of callbacks used to handle newly-connecting clients. | ||
18 | */ | ||
19 | typedef void (*GNUNET_DBUS_ClientConnectsHandler)( | ||
20 | struct GNUNET_DBUS_Service *service, | ||
21 | struct GNUNET_DBUS_Client *client); | ||
22 | |||
23 | /** | ||
24 | * The type of callbacks used to handle clients disconnecting. | ||
25 | */ | ||
26 | typedef void (*GNUNET_DBUS_ClientDisconnectsHandler)( | ||
27 | struct GNUNET_DBUS_Service *service, | ||
28 | struct GNUNET_DBUS_Client *client); | ||
29 | |||
30 | /** | ||
31 | * Create a service with the given name and configuration. The service will | ||
32 | * start running immediately in GNUnet's scheduler. | ||
33 | */ | ||
34 | struct GNUNET_DBUS_Service * | ||
35 | GNUNET_DBUS_service_create ( | ||
36 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
37 | const char *name); | ||
38 | |||
39 | /** | ||
40 | * Increase the reference count of this GNUNET_DBUS_Service by one. | ||
41 | */ | ||
42 | void | ||
43 | GNUNET_DBUS_service_ref ( | ||
44 | struct GNUNET_DBUS_Service *service); | ||
45 | |||
46 | /** | ||
47 | * Decrease the reference count of this GNUNET_DBUS_Service by one. Will free | ||
48 | * the service if the reference count reaches zero. | ||
49 | */ | ||
50 | void | ||
51 | GNUNET_DBUS_service_unref ( | ||
52 | struct GNUNET_DBUS_Service *service); | ||
53 | |||
54 | /** | ||
55 | * Get a reference to this GNUNET_DBUS_Service's configuration. | ||
56 | */ | ||
57 | const struct GNUNET_CONFIGURATION_Handle * | ||
58 | GNUNET_DBUS_service_get_config ( | ||
59 | struct GNUNET_DBUS_Service *service); | ||
60 | |||
61 | /** | ||
62 | * Send an arbitrary message from this service. | ||
63 | */ | ||
64 | void | ||
65 | GNUNET_DBUS_service_send ( | ||
66 | struct GNUNET_DBUS_Service *service, | ||
67 | DBusMessage *dbus_message); | ||
68 | |||
69 | /** | ||
70 | * Set the callbacks used by this service to handle clients connecting and | ||
71 | * disconnecting. | ||
72 | */ | ||
73 | void | ||
74 | GNUNET_DBUS_service_set_client_handlers ( | ||
75 | struct GNUNET_DBUS_Service *service, | ||
76 | GNUNET_DBUS_ClientConnectsHandler client_connects, | ||
77 | GNUNET_DBUS_ClientDisconnectsHandler client_disconnects); | ||
78 | |||
79 | /** | ||
80 | * Get this GNUNET_DBUS_Service's root object (a.k.a. '/') | ||
81 | */ | ||
82 | struct GNUNET_DBUS_Object * | ||
83 | GNUNET_DBUS_service_get_root_object ( | ||
84 | struct GNUNET_DBUS_Service *service); | ||
85 | |||
86 | #endif | ||
87 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_signal.h b/src/lib/include/gnunet_dbus_lib_signal.h new file mode 100644 index 0000000..af314fe --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_signal.h | |||
@@ -0,0 +1,102 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_SIGNAL_H | ||
2 | #define GNUNET_DBUS_LIB_SIGNAL_H | ||
3 | |||
4 | /** | ||
5 | * Defines a DBus signal that may be sent from an interface. | ||
6 | */ | ||
7 | struct GNUNET_DBUS_Signal; | ||
8 | |||
9 | #include "gnunet_dbus_lib_object_path.h" | ||
10 | #include "gnunet_dbus_lib_interface.h" | ||
11 | |||
12 | /** | ||
13 | * An iterable, double-linked-list of GNUNET_DBUS_Signal. | ||
14 | */ | ||
15 | struct GNUNET_DBUS_SignalIterator | ||
16 | { | ||
17 | /* linked list */ | ||
18 | struct GNUNET_DBUS_SignalIterator *next; | ||
19 | struct GNUNET_DBUS_SignalIterator *prev; | ||
20 | |||
21 | struct GNUNET_DBUS_Signal *signal; | ||
22 | }; | ||
23 | |||
24 | /** | ||
25 | * Create a signal with the given name. The signal should be populated with | ||
26 | * argument definitions then bound to an interface with | ||
27 | * GNUNET_DBUS_interface_add_signal. | ||
28 | */ | ||
29 | struct GNUNET_DBUS_Signal * | ||
30 | GNUNET_DBUS_signal_create ( | ||
31 | const char *name); | ||
32 | |||
33 | /** | ||
34 | * Increase the reference count of this GNUNET_DBUS_Signal by one. | ||
35 | */ | ||
36 | void | ||
37 | GNUNET_DBUS_signal_ref ( | ||
38 | struct GNUNET_DBUS_Signal *signal); | ||
39 | |||
40 | /** | ||
41 | * Decrease the reference count of this GNUNET_DBUS_Signal by one. Will free | ||
42 | * the GNUNET_DBUS_Signal if the reference count reaches zero. | ||
43 | */ | ||
44 | void | ||
45 | GNUNET_DBUS_signal_unref ( | ||
46 | struct GNUNET_DBUS_Signal *signal); | ||
47 | |||
48 | /** | ||
49 | * Adds an argument definition to this GNUNET_DBUS_Signal given both it's name | ||
50 | * and it's DBus type signature. | ||
51 | */ | ||
52 | void | ||
53 | GNUNET_DBUS_signal_add_arg ( | ||
54 | struct GNUNET_DBUS_Signal *signal, | ||
55 | const char *name, | ||
56 | const char *signature); | ||
57 | |||
58 | /** | ||
59 | * Get the name of this GNUNET_DBUS_Signal. | ||
60 | */ | ||
61 | const char * | ||
62 | GNUNET_DBUS_signal_get_name ( | ||
63 | const struct GNUNET_DBUS_Signal *signal); | ||
64 | |||
65 | /** | ||
66 | * Iterate over the arguments of this GNUNET_DBUS_Signal. | ||
67 | */ | ||
68 | const struct GNUNET_DBUS_ArgIterator * | ||
69 | GNUNET_DBUS_signal_iterate_args ( | ||
70 | const struct GNUNET_DBUS_Signal *signal); | ||
71 | |||
72 | /** | ||
73 | * Instantiate the signal so that it can be sent to all interested peers on the | ||
74 | * bus. The returned DBusMessage must be populated with the signal's arguments | ||
75 | * and can then be sent to send the signal. The signal will originate from the | ||
76 | * supplied object path and interface. pretty sets whether data pushed to the | ||
77 | * returned DBusMessage will be prety-encoded. | ||
78 | */ | ||
79 | DBusMessage * | ||
80 | GNUNET_DBUS_signal_spawn ( | ||
81 | const struct GNUNET_DBUS_Signal *signal, | ||
82 | const struct GNUNET_DBUS_ObjectPath *path, | ||
83 | const struct GNUNET_DBUS_Interface *interface, | ||
84 | bool pretty); | ||
85 | |||
86 | /** | ||
87 | * Instantiate the signal so that it can be sent to a single client. The | ||
88 | * returned DBusMessage must be populated with the signal's arguments and can | ||
89 | * then be sent to send the signal. The signal will originate from the supplied | ||
90 | * object path and interface. pretty sets whether data pushed to the returned | ||
91 | * DBusMessage will be prety-encoded. | ||
92 | */ | ||
93 | DBusMessage * | ||
94 | GNUNET_DBUS_signal_spawn_unicast ( | ||
95 | const struct GNUNET_DBUS_Signal *signal, | ||
96 | const struct GNUNET_DBUS_ObjectPath *path, | ||
97 | const struct GNUNET_DBUS_Interface *interface, | ||
98 | const struct GNUNET_DBUS_Client *client, | ||
99 | bool pretty); | ||
100 | |||
101 | #endif | ||
102 | |||
diff --git a/src/lib/include/gnunet_dbus_lib_signature.h b/src/lib/include/gnunet_dbus_lib_signature.h new file mode 100644 index 0000000..b5ebc84 --- /dev/null +++ b/src/lib/include/gnunet_dbus_lib_signature.h | |||
@@ -0,0 +1,42 @@ | |||
1 | #ifndef GNUNET_DBUS_LIB_SIGNATURE_H | ||
2 | #define GNUNET_DBUS_LIB_SIGNATURE_H | ||
3 | |||
4 | #include <dbus/dbus.h> | ||
5 | #include "gnunet_crypto_dbus_lib.h" | ||
6 | |||
7 | #define GNUNET_DBUS_SIGNATURE_BYTE DBUS_TYPE_BYTE_AS_STRING | ||
8 | #define GNUNET_DBUS_SIGNATURE_BOOLEAN DBUS_TYPE_BOOLEAN_AS_STRING | ||
9 | #define GNUNET_DBUS_SIGNATURE_INT16 DBUS_TYPE_INT16_AS_STRING | ||
10 | #define GNUNET_DBUS_SIGNATURE_UINT16 DBUS_TYPE_UINT16_AS_STRING | ||
11 | #define GNUNET_DBUS_SIGNATURE_INT32 DBUS_TYPE_INT32_AS_STRING | ||
12 | #define GNUNET_DBUS_SIGNATURE_UINT32 DBUS_TYPE_UINT32_AS_STRING | ||
13 | #define GNUNET_DBUS_SIGNATURE_INT64 DBUS_TYPE_INT64_AS_STRING | ||
14 | #define GNUNET_DBUS_SIGNATURE_UINT64 DBUS_TYPE_UINT64_AS_STRING | ||
15 | #define GNUNET_DBUS_SIGNATURE_DOUBLE DBUS_TYPE_DOUBLE_AS_STRING | ||
16 | #define GNUNET_DBUS_SIGNATURE_STRING DBUS_TYPE_STRING_AS_STRING | ||
17 | #define GNUNET_DBUS_SIGNATURE_OBJECT_PATH DBUS_TYPE_OBJECT_PATH_AS_STRING | ||
18 | #define GNUNET_DBUS_SIGNATURE_SIGNATURE DBUS_TYPE_SIGNATURE_AS_STRING | ||
19 | #define GNUNET_DBUS_SIGNATURE_UNIX_FD DBUS_TYPE_UNIX_FD_AS_STRING | ||
20 | #define GNUNET_DBUS_SIGNATURE_VARIANT DBUS_TYPE_VARIANT_AS_STRING | ||
21 | |||
22 | #define GNUNET_DBUS_SIGNATURE_ARRAY(s) DBUS_TYPE_ARRAY_AS_STRING s | ||
23 | #define GNUNET_DBUS_SIGNATURE_DICT(s) DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING s DBUS_DICT_ENTRY_END_CHAR_AS_STRING | ||
24 | #define GNUNET_DBUS_SIGNATURE_STRUCT(s) DBUS_STRUCT_BEGIN_CHAR_AS_STRING s DBUS_STRUCT_END_CHAR_AS_STRING | ||
25 | |||
26 | #define GNUNET_DBUS_SIGNATURE_BITFIELD GNUNET_DBUS_SIGNATURE_VARIANT | ||
27 | #define GNUNET_DBUS_SIGNATURE_ENUM GNUNET_DBUS_SIGNATURE_VARIANT | ||
28 | |||
29 | #define GNUNET_DBUS_SIGNATURE_HASHCODE GNUNET_DBUS_SIGNATURE_VARIANT | ||
30 | #define GNUNET_DBUS_SIGNATURE_PEER_IDENTITY GNUNET_DBUS_SIGNATURE_STRUCT(GNUNET_CRYPTO_DBUS_SIGNATURE_EDDSA_PUBLIC_KEY) | ||
31 | |||
32 | /** | ||
33 | * Formats the given DBus typecode as a string. For example, | ||
34 | * GNUNET_DBUS_signature_typecode_to_string(DBUS_TYPE_UINT32) will return the | ||
35 | * constant string "u" | ||
36 | */ | ||
37 | const char * | ||
38 | GNUNET_DBUS_signature_typecode_to_string ( | ||
39 | int typecode); | ||
40 | |||
41 | #endif | ||
42 | |||
diff --git a/src/lib/include/gnunet_dht_dbus_lib.h b/src/lib/include/gnunet_dht_dbus_lib.h new file mode 100644 index 0000000..0281f92 --- /dev/null +++ b/src/lib/include/gnunet_dht_dbus_lib.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef GNUNET_DHT_DBUS_LIB_H | ||
2 | #define GNUNET_DHT_DBUS_LIB_H | ||
3 | |||
4 | #include <dbus/dbus.h> | ||
5 | #include <gnunet/platform.h> | ||
6 | #include <gnunet/gnunet_common.h> | ||
7 | #include <gnunet/gnunet_dht_service.h> | ||
8 | |||
9 | #include <gnunet_dbus_lib.h> | ||
10 | |||
11 | /** | ||
12 | * A {NULL, 0}-terminated list of textual descriptions of | ||
13 | * `GNUNET_DHT_RouteOption` enum variants. Used for converting back-and-forth | ||
14 | * between `GNUNET_DHT_RouteOption` and `const char *` | ||
15 | */ | ||
16 | extern const struct GNUNET_DBUS_StringEnumPair GNUNET_DHT_DBUS_route_option_description[]; | ||
17 | |||
18 | #include "gnunet_dht_dbus_lib_push.h" | ||
19 | #include "gnunet_dht_dbus_lib_pop.h" | ||
20 | #include "gnunet_dht_dbus_lib_signature.h" | ||
21 | |||
22 | #endif | ||
23 | |||
diff --git a/src/lib/include/gnunet_dht_dbus_lib_pop.h b/src/lib/include/gnunet_dht_dbus_lib_pop.h new file mode 100644 index 0000000..e69587b --- /dev/null +++ b/src/lib/include/gnunet_dht_dbus_lib_pop.h | |||
@@ -0,0 +1,19 @@ | |||
1 | #ifndef GNUNET_DHT_DBUS_LIB_POP_H | ||
2 | #define GNUNET_DHT_DBUS_LIB_POP_H | ||
3 | |||
4 | #include "gnunet_dht_dbus_lib.h" | ||
5 | |||
6 | /** | ||
7 | * Pop a GNUNET_DHT_RouteOption from a DBusMessage, advancing the iterator. | ||
8 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
9 | * message is missing or the wrong type. | ||
10 | */ | ||
11 | DBusMessage * | ||
12 | GNUNET_DHT_DBUS_pop_route_option ( | ||
13 | DBusMessage *message, | ||
14 | DBusMessageIter *iter, | ||
15 | const char *arg_name, | ||
16 | enum GNUNET_DHT_RouteOption *value); | ||
17 | |||
18 | #endif | ||
19 | |||
diff --git a/src/lib/include/gnunet_dht_dbus_lib_push.h b/src/lib/include/gnunet_dht_dbus_lib_push.h new file mode 100644 index 0000000..44e83be --- /dev/null +++ b/src/lib/include/gnunet_dht_dbus_lib_push.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef GNUNET_DHT_DBUS_LIB_PUSH_H | ||
2 | #define GNUNET_DHT_DBUS_LIB_PUSH_H | ||
3 | |||
4 | #include "gnunet_dht_dbus_lib.h" | ||
5 | |||
6 | /** | ||
7 | * Push a GNUNET_DHT_RouteOption to the DBusMessage, advancing the iterator. | ||
8 | */ | ||
9 | void | ||
10 | GNUNET_DHT_DBUS_push_route_option ( | ||
11 | DBusMessage *message, | ||
12 | DBusMessageIter *iter, | ||
13 | const enum GNUNET_DHT_RouteOption *value); | ||
14 | |||
15 | #endif | ||
16 | |||
diff --git a/src/lib/include/gnunet_dht_dbus_lib_signature.h b/src/lib/include/gnunet_dht_dbus_lib_signature.h new file mode 100644 index 0000000..d8f2092 --- /dev/null +++ b/src/lib/include/gnunet_dht_dbus_lib_signature.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef GNUNET_DHT_DBUS_LIB_SIGNATURE_H | ||
2 | #define GNUNET_DHT_DBUS_LIB_SIGNATURE_H | ||
3 | |||
4 | #include "gnunet_dbus_lib.h" | ||
5 | |||
6 | #define GNUNET_DHT_DBUS_SIGNATURE_ROUTE_OPTION GNUNET_DBUS_SIGNATURE_VARIANT | ||
7 | |||
8 | #endif | ||
9 | |||
diff --git a/src/lib/include/gnunet_gnsrecord_dbus_lib.h b/src/lib/include/gnunet_gnsrecord_dbus_lib.h new file mode 100644 index 0000000..6f36c45 --- /dev/null +++ b/src/lib/include/gnunet_gnsrecord_dbus_lib.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef GNUNET_GNSRECORD_DBUS_LIB_H | ||
2 | #define GNUNET_GNSRECORD_DBUS_LIB_H | ||
3 | |||
4 | #include <gnunet_dbus_lib.h> | ||
5 | |||
6 | /** | ||
7 | * A {NULL, 0}-terminate array of textual descriptions of the different | ||
8 | * GNUNET_GNSRECORD_Flags flags. | ||
9 | */ | ||
10 | const struct GNUNET_DBUS_StringEnumPair *GNUNET_GNSRECORD_DBUS_describe_flags(); | ||
11 | |||
12 | #include "gnunet_gnsrecord_dbus_lib_push.h" | ||
13 | #include "gnunet_gnsrecord_dbus_lib_pop.h" | ||
14 | #include "gnunet_gnsrecord_dbus_lib_signature.h" | ||
15 | |||
16 | #endif | ||
17 | |||
diff --git a/src/lib/include/gnunet_gnsrecord_dbus_lib_pop.h b/src/lib/include/gnunet_gnsrecord_dbus_lib_pop.h new file mode 100644 index 0000000..97eec2e --- /dev/null +++ b/src/lib/include/gnunet_gnsrecord_dbus_lib_pop.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef GNUNET_GNSRECORD_DBUS_LIB_POP_H | ||
2 | #define GNUNET_GNSRECORD_DBUS_LIB_POP_H | ||
3 | |||
4 | /** | ||
5 | * Pop a GNUNET_GNSRECORD_Type from a DBusMessage, advancing the iterator. | ||
6 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
7 | * message is missing or the wrong type. | ||
8 | */ | ||
9 | DBusMessage * | ||
10 | GNUNET_GNSRECORD_DBUS_pop_type ( | ||
11 | DBusMessage *message, | ||
12 | DBusMessageIter *iter, | ||
13 | const char *arg_name, | ||
14 | uint32_t *value); | ||
15 | |||
16 | /** | ||
17 | * Pop a GNUNET_GNSRECORD_Flags from a DBusMessage, advancing the iterator. | ||
18 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
19 | * message is missing or the wrong type. | ||
20 | */ | ||
21 | DBusMessage * | ||
22 | GNUNET_GNSRECORD_DBUS_pop_flags ( | ||
23 | DBusMessage *message, | ||
24 | DBusMessageIter *iter, | ||
25 | const char *arg_name, | ||
26 | enum GNUNET_GNSRECORD_Flags *value); | ||
27 | |||
28 | #endif | ||
29 | |||
diff --git a/src/lib/include/gnunet_gnsrecord_dbus_lib_push.h b/src/lib/include/gnunet_gnsrecord_dbus_lib_push.h new file mode 100644 index 0000000..0fdfc6c --- /dev/null +++ b/src/lib/include/gnunet_gnsrecord_dbus_lib_push.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef GNUNET_GNSRECORD_DBUS_LIB_PUSH_H | ||
2 | #define GNUNET_GNSRECORD_DBUS_LIB_PUSH_H | ||
3 | |||
4 | #include <gnunet/platform.h> | ||
5 | #include <gnunet/gnunet_common.h> | ||
6 | #include <gnunet/gnunet_gnsrecord_lib.h> | ||
7 | |||
8 | #include "gnunet_gnsrecord_dbus_lib.h" | ||
9 | |||
10 | /** | ||
11 | * Push a GNUNET_GNSRECORD_Type to a DBusMessage, advancing the iterator. | ||
12 | */ | ||
13 | void | ||
14 | GNUNET_GNSRECORD_DBUS_push_type ( | ||
15 | DBusMessage *message, | ||
16 | DBusMessageIter *iter, | ||
17 | const uint32_t *value); | ||
18 | |||
19 | /** | ||
20 | * Push a GNUNET_GNSRECORD_Flags to a DBusMessage, advancing the iterator. | ||
21 | */ | ||
22 | void | ||
23 | GNUNET_GNSRECORD_DBUS_push_flags ( | ||
24 | DBusMessage *message, | ||
25 | DBusMessageIter *iter, | ||
26 | const enum GNUNET_GNSRECORD_Flags *value); | ||
27 | |||
28 | /** | ||
29 | * Push a GNUNET_GNSRECORD_Data to a DBusMessage, advancing the iterator. | ||
30 | */ | ||
31 | void | ||
32 | GNUNET_GNSRECORD_DBUS_push_data ( | ||
33 | DBusMessage *message, | ||
34 | DBusMessageIter *iter, | ||
35 | const struct GNUNET_GNSRECORD_Data *value); | ||
36 | |||
37 | #endif | ||
38 | |||
diff --git a/src/lib/include/gnunet_gnsrecord_dbus_lib_signature.h b/src/lib/include/gnunet_gnsrecord_dbus_lib_signature.h new file mode 100644 index 0000000..bda353a --- /dev/null +++ b/src/lib/include/gnunet_gnsrecord_dbus_lib_signature.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef GNUNET_GNSRECORD_DBUS_LIB_SIGNATURE_H | ||
2 | #define GNUNET_GNSRECORD_DBUS_LIB_SIGNATURE_H | ||
3 | |||
4 | #include "gnunet_time_dbus_lib_signature.h" | ||
5 | #include "gnunet_crypto_dbus_lib_signature.h" | ||
6 | |||
7 | #define GNUNET_GNSRECORD_DBUS_SIGNATURE_TYPE GNUNET_DBUS_SIGNATURE_VARIANT | ||
8 | #define GNUNET_GNSRECORD_DBUS_SIGNATURE_FLAGS GNUNET_DBUS_SIGNATURE_BITFIELD | ||
9 | |||
10 | #define GNUNET_GNSRECORD_DBUS_SIGNATURE_DATA \ | ||
11 | GNUNET_DBUS_SIGNATURE_STRUCT ( \ | ||
12 | GNUNET_GNSRECORD_DBUS_SIGNATURE_TYPE \ | ||
13 | GNUNET_GNSRECORD_DBUS_SIGNATURE_FLAGS \ | ||
14 | GNUNET_DBUS_SIGNATURE_VARIANT \ | ||
15 | GNUNET_DBUS_SIGNATURE_VARIANT \ | ||
16 | ) | ||
17 | |||
18 | #define GNUNET_GNSRECORD_DBUS_SIGNATURE_BLOCK \ | ||
19 | GNUNET_DBUS_SIGNATURE_STRUCT ( \ | ||
20 | GNUNET_CRYPTO_DBUS_SIGNATURE_ECDSA_SIGNATURE \ | ||
21 | GNUNET_CRYPTO_DBUS_SIGNATURE_ECDSA_PUBLIC_KEY \ | ||
22 | GNUNET_CRYPTO_DBUS_SIGNATURE_ECC_SIGNATURE_PURPOSE \ | ||
23 | GNUNET_TIME_DBUS_SIGNATURE_ABSOLUTE \ | ||
24 | ) | ||
25 | |||
26 | #endif | ||
27 | |||
diff --git a/src/lib/include/gnunet_time_dbus_lib.h b/src/lib/include/gnunet_time_dbus_lib.h new file mode 100644 index 0000000..73046e9 --- /dev/null +++ b/src/lib/include/gnunet_time_dbus_lib.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef GNUNET_TIME_DBUS_LIB_H | ||
2 | #define GNUNET_TIME_DBUS_LIB_H | ||
3 | |||
4 | #include <gnunet_dbus_lib.h> | ||
5 | |||
6 | #include "gnunet_time_dbus_lib_push.h" | ||
7 | #include "gnunet_time_dbus_lib_pop.h" | ||
8 | #include "gnunet_time_dbus_lib_signature.h" | ||
9 | |||
10 | #endif | ||
11 | |||
diff --git a/src/lib/include/gnunet_time_dbus_lib_pop.h b/src/lib/include/gnunet_time_dbus_lib_pop.h new file mode 100644 index 0000000..a1f0456 --- /dev/null +++ b/src/lib/include/gnunet_time_dbus_lib_pop.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef GNUNET_TIME_DBUS_LIB_POP_H | ||
2 | #define GNUNET_TIME_DBUS_LIB_POP_H | ||
3 | |||
4 | /** | ||
5 | * Pop a GNUNET_TIME_Absolute from a DBusMessage, advancing the iterator. | ||
6 | * `arg_name` is used for reporting useful diagnostics if the value in the | ||
7 | * message is missing or the wrong type. | ||
8 | */ | ||
9 | DBusMessage * | ||
10 | GNUNET_TIME_DBUS_pop_absolute ( | ||
11 | DBusMessage *message, | ||
12 | DBusMessageIter *iter, | ||
13 | const char *arg_name, | ||
14 | struct GNUNET_TIME_Absolute *value); | ||
15 | |||
16 | #endif | ||
17 | |||
diff --git a/src/lib/include/gnunet_time_dbus_lib_push.h b/src/lib/include/gnunet_time_dbus_lib_push.h new file mode 100644 index 0000000..8469e31 --- /dev/null +++ b/src/lib/include/gnunet_time_dbus_lib_push.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef GNUNET_TIME_DBUS_LIB_PUSH_H | ||
2 | #define GNUNET_TIME_DBUS_LIB_PUSH_H | ||
3 | |||
4 | /** | ||
5 | * Push a GNUNET_TIME_Absolute to DBusMessage, advancing the iterator. | ||
6 | */ | ||
7 | void | ||
8 | GNUNET_TIME_DBUS_push_absolute ( | ||
9 | DBusMessage *message, | ||
10 | DBusMessageIter *iter, | ||
11 | const struct GNUNET_TIME_Absolute *value); | ||
12 | |||
13 | /** | ||
14 | * Push a GNUNET_TIME_Relative to DBusMessage, advancing the iterator. | ||
15 | */ | ||
16 | void | ||
17 | GNUNET_TIME_DBUS_push_relative ( | ||
18 | DBusMessage *message, | ||
19 | DBusMessageIter *iter, | ||
20 | const struct GNUNET_TIME_Relative *value); | ||
21 | |||
22 | #endif | ||
23 | |||
diff --git a/src/lib/include/gnunet_time_dbus_lib_signature.h b/src/lib/include/gnunet_time_dbus_lib_signature.h new file mode 100644 index 0000000..d05f4aa --- /dev/null +++ b/src/lib/include/gnunet_time_dbus_lib_signature.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef GNUNET_TIME_DBUS_LIB_SIGNATURE_H | ||
2 | #define GNUNET_TIME_DBUS_LIB_SIGNATURE_H | ||
3 | |||
4 | #include "gnunet_dbus_lib.h" | ||
5 | |||
6 | #define GNUNET_TIME_DBUS_SIGNATURE_ABSOLUTE GNUNET_DBUS_SIGNATURE_VARIANT | ||
7 | #define GNUNET_TIME_DBUS_SIGNATURE_RELATIVE GNUNET_DBUS_SIGNATURE_VARIANT | ||
8 | |||
9 | #endif | ||
10 | |||
diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am new file mode 100644 index 0000000..f7f6b7c --- /dev/null +++ b/src/lib/util/Makefile.am | |||
@@ -0,0 +1,27 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | lib_LTLIBRARIES = \ | ||
3 | libgnunettimedbus.la \ | ||
4 | libgnunetcryptodbus.la | ||
5 | |||
6 | libgnunettimedbus_la_SOURCES = \ | ||
7 | gnunet_time_dbus_lib_pop.c \ | ||
8 | gnunet_time_dbus_lib_push.c | ||
9 | |||
10 | libgnunettimedbus_la_CFLAGS = \ | ||
11 | -I$(top_builddir)/src/lib/include \ | ||
12 | $(DBUS_CFLAGS) | ||
13 | |||
14 | libgnunettimedbus_la_LDFLAGS = \ | ||
15 | $(DBUS_LIBS) | ||
16 | |||
17 | libgnunetcryptodbus_la_SOURCES = \ | ||
18 | gnunet_crypto_dbus_lib_pop.c \ | ||
19 | gnunet_crypto_dbus_lib_push.c | ||
20 | |||
21 | libgnunetcryptodbus_la_CFLAGS = \ | ||
22 | -I$(top_builddir)/src/lib/include \ | ||
23 | $(DBUS_CFLAGS) | ||
24 | |||
25 | libgnunetcryptodbus_la_LDFLAGS = \ | ||
26 | $(DBUS_LIBS) | ||
27 | |||
diff --git a/src/lib/util/gnunet_crypto_dbus_lib_pop.c b/src/lib/util/gnunet_crypto_dbus_lib_pop.c new file mode 100644 index 0000000..a598f1d --- /dev/null +++ b/src/lib/util/gnunet_crypto_dbus_lib_pop.c | |||
@@ -0,0 +1,145 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_dbus_lib.h" | ||
4 | |||
5 | DBusMessage * | ||
6 | GNUNET_CRYPTO_DBUS_pop_ecdsa_public_key ( | ||
7 | DBusMessage *message, | ||
8 | DBusMessageIter *iter, | ||
9 | const char *arg_name, | ||
10 | struct GNUNET_CRYPTO_EcdsaPublicKey *value) | ||
11 | { | ||
12 | DBusMessage *ret = NULL; | ||
13 | DBusMessageIter iter_sub; | ||
14 | DBusMessageIter iter_sub_sub; | ||
15 | |||
16 | ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
17 | if (ret) | ||
18 | return ret; | ||
19 | |||
20 | const char *encoded; | ||
21 | int success; | ||
22 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
23 | int element_type; | ||
24 | int n_elements; | ||
25 | unsigned char *marshalled_array; | ||
26 | switch (arg_type) | ||
27 | { | ||
28 | case DBUS_TYPE_STRING: | ||
29 | dbus_message_iter_get_basic (&iter_sub, &encoded); | ||
30 | success = GNUNET_CRYPTO_ecdsa_public_key_from_string (encoded, strlen (encoded), value); | ||
31 | if (GNUNET_OK != success) | ||
32 | { | ||
33 | return dbus_message_new_error_printf ( | ||
34 | message, | ||
35 | DBUS_ERROR_INVALID_ARGS, | ||
36 | "String is not a valid base32 encoded ECDSA public key for argument '%s'", | ||
37 | arg_name); | ||
38 | } | ||
39 | GNUNET_DBUS_message_set_pretty (message, true); | ||
40 | return NULL; | ||
41 | case DBUS_TYPE_ARRAY: | ||
42 | element_type = dbus_message_iter_get_element_type (&iter_sub); | ||
43 | if (DBUS_TYPE_BYTE == element_type) | ||
44 | { | ||
45 | dbus_message_iter_recurse (&iter_sub, &iter_sub_sub); | ||
46 | dbus_message_iter_get_fixed_array (&iter_sub_sub, &marshalled_array, &n_elements); | ||
47 | if (sizeof (value->q_y) == n_elements) | ||
48 | { | ||
49 | memcpy (value->q_y, marshalled_array, n_elements); | ||
50 | return NULL; | ||
51 | }; | ||
52 | return dbus_message_new_error_printf ( | ||
53 | message, | ||
54 | DBUS_ERROR_INVALID_ARGS, | ||
55 | "ECDSA public key consists of 32 bytes (256 bits). Array given for argument '%s' contains %d bytes.", | ||
56 | arg_name, | ||
57 | n_elements); | ||
58 | }; | ||
59 | return dbus_message_new_error_printf ( | ||
60 | message, | ||
61 | DBUS_ERROR_INVALID_ARGS, | ||
62 | "Invalid type for argument '%s'. Variant contains an array of '%s'. Should contain an ECDSA public key in the form of a base32 encoded string or an array of 32 bytes (256 bits).", | ||
63 | arg_name, | ||
64 | GNUNET_DBUS_signature_typecode_to_string (element_type)); | ||
65 | default: | ||
66 | return dbus_message_new_error_printf ( | ||
67 | message, | ||
68 | DBUS_ERROR_INVALID_ARGS, | ||
69 | "Invalid type in variant for argument '%s'. Should contain an ECDSA public key in the form of a base32 encoded string or an array of 32 bytes (256 bits). Contains '%s'", | ||
70 | arg_name, | ||
71 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | DBusMessage * | ||
76 | GNUNET_CRYPTO_DBUS_pop_eddsa_public_key ( | ||
77 | DBusMessage *message, | ||
78 | DBusMessageIter *iter, | ||
79 | const char *arg_name, | ||
80 | struct GNUNET_CRYPTO_EddsaPublicKey *value) | ||
81 | { | ||
82 | DBusMessage *ret = NULL; | ||
83 | DBusMessageIter iter_sub; | ||
84 | DBusMessageIter iter_sub_sub; | ||
85 | |||
86 | ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
87 | if (ret) | ||
88 | return ret; | ||
89 | |||
90 | const char *encoded; | ||
91 | int success; | ||
92 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
93 | int element_type; | ||
94 | int n_elements; | ||
95 | unsigned char *marshalled_array; | ||
96 | switch (arg_type) | ||
97 | { | ||
98 | case DBUS_TYPE_STRING: | ||
99 | dbus_message_iter_get_basic (&iter_sub, &encoded); | ||
100 | success = GNUNET_CRYPTO_eddsa_public_key_from_string (encoded, strlen (encoded), value); | ||
101 | if (GNUNET_OK != success) | ||
102 | { | ||
103 | return dbus_message_new_error_printf ( | ||
104 | message, | ||
105 | DBUS_ERROR_INVALID_ARGS, | ||
106 | "String is not a valid base32 encoded EDDSA public key for argument '%s'", | ||
107 | arg_name); | ||
108 | } | ||
109 | GNUNET_DBUS_message_set_pretty (message, true); | ||
110 | return NULL; | ||
111 | case DBUS_TYPE_ARRAY: | ||
112 | element_type = dbus_message_iter_get_element_type (&iter_sub); | ||
113 | if (DBUS_TYPE_BYTE == element_type) | ||
114 | { | ||
115 | dbus_message_iter_recurse (&iter_sub, &iter_sub_sub); | ||
116 | dbus_message_iter_get_fixed_array (&iter_sub_sub, &marshalled_array, &n_elements); | ||
117 | if (sizeof (value->q_y) == n_elements) | ||
118 | { | ||
119 | memcpy (value->q_y, marshalled_array, n_elements); | ||
120 | return NULL; | ||
121 | }; | ||
122 | return dbus_message_new_error_printf ( | ||
123 | message, | ||
124 | DBUS_ERROR_INVALID_ARGS, | ||
125 | "EDDSA public key consists of 32 bytes (256 bits). Array given for argument '%s' contains %d bytes.", | ||
126 | arg_name, | ||
127 | n_elements); | ||
128 | }; | ||
129 | return dbus_message_new_error_printf ( | ||
130 | message, | ||
131 | DBUS_ERROR_INVALID_ARGS, | ||
132 | "Invalid type for argument '%s'. Variant contains an array of '%s'. Should contain an EDDSA public key in the form of a base32 encoded string or an array of 32 bytes (256 bits).", | ||
133 | arg_name, | ||
134 | GNUNET_DBUS_signature_typecode_to_string (element_type)); | ||
135 | default: | ||
136 | return dbus_message_new_error_printf ( | ||
137 | message, | ||
138 | DBUS_ERROR_INVALID_ARGS, | ||
139 | "Invalid type in variant for argument '%s'. Should contain an ECDSA public key in the form of a base32 encoded string or an array of 32 bytes (256 bits). Contains '%s'", | ||
140 | arg_name, | ||
141 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | |||
diff --git a/src/lib/util/gnunet_crypto_dbus_lib_push.c b/src/lib/util/gnunet_crypto_dbus_lib_push.c new file mode 100644 index 0000000..6e1cd3a --- /dev/null +++ b/src/lib/util/gnunet_crypto_dbus_lib_push.c | |||
@@ -0,0 +1,54 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include "gnunet_dbus_lib.h" | ||
4 | |||
5 | void | ||
6 | GNUNET_CRYPTO_DBUS_push_ecdsa_public_key ( | ||
7 | DBusMessage *message, | ||
8 | DBusMessageIter *iter, | ||
9 | const struct GNUNET_CRYPTO_EcdsaPublicKey *value) | ||
10 | { | ||
11 | DBusMessageIter iter_sub; | ||
12 | |||
13 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
14 | { | ||
15 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
16 | char *encoded = GNUNET_CRYPTO_ecdsa_public_key_to_string (value); | ||
17 | const char *encoded_const = encoded; | ||
18 | GNUNET_DBUS_push_string (message, &iter_sub, &encoded_const); | ||
19 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
20 | GNUNET_free (encoded); | ||
21 | } | ||
22 | else | ||
23 | { | ||
24 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_ARRAY (GNUNET_DBUS_SIGNATURE_BYTE)); | ||
25 | GNUNET_DBUS_push_byte_array (message, &iter_sub, value->q_y, 32); | ||
26 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
27 | }; | ||
28 | }; | ||
29 | |||
30 | void | ||
31 | GNUNET_CRYPTO_DBUS_push_eddsa_public_key ( | ||
32 | DBusMessage *message, | ||
33 | DBusMessageIter *iter, | ||
34 | const struct GNUNET_CRYPTO_EddsaPublicKey *value) | ||
35 | { | ||
36 | DBusMessageIter iter_sub; | ||
37 | |||
38 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
39 | { | ||
40 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
41 | char *encoded = GNUNET_CRYPTO_eddsa_public_key_to_string (value); | ||
42 | const char *encoded_const = encoded; | ||
43 | GNUNET_DBUS_push_string (message, &iter_sub, &encoded_const); | ||
44 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
45 | GNUNET_free (encoded); | ||
46 | } | ||
47 | else | ||
48 | { | ||
49 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_ARRAY (GNUNET_DBUS_SIGNATURE_BYTE)); | ||
50 | GNUNET_DBUS_push_byte_array (message, &iter_sub, value->q_y, 32); | ||
51 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
52 | }; | ||
53 | }; | ||
54 | |||
diff --git a/src/lib/util/gnunet_time_dbus_lib_pop.c b/src/lib/util/gnunet_time_dbus_lib_pop.c new file mode 100644 index 0000000..10322c6 --- /dev/null +++ b/src/lib/util/gnunet_time_dbus_lib_pop.c | |||
@@ -0,0 +1,52 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_strings_lib.h> | ||
6 | |||
7 | #include "gnunet_time_dbus_lib.h" | ||
8 | |||
9 | DBusMessage * | ||
10 | GNUNET_TIME_DBUS_pop_absolute ( | ||
11 | DBusMessage *message, | ||
12 | DBusMessageIter *iter, | ||
13 | const char *arg_name, | ||
14 | struct GNUNET_TIME_Absolute *value) | ||
15 | { | ||
16 | DBusMessageIter iter_sub; | ||
17 | DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name); | ||
18 | if (ret) | ||
19 | return ret; | ||
20 | |||
21 | int arg_type = dbus_message_iter_get_arg_type (&iter_sub); | ||
22 | switch (arg_type) | ||
23 | { | ||
24 | case DBUS_TYPE_STRING: { | ||
25 | const char *time; | ||
26 | dbus_message_iter_get_basic (&iter_sub, &time); | ||
27 | int err = GNUNET_STRINGS_fancy_time_to_absolute (time, value); | ||
28 | if (GNUNET_OK != err) | ||
29 | { | ||
30 | return dbus_message_new_error_printf ( | ||
31 | message, | ||
32 | DBUS_ERROR_INVALID_ARGS, | ||
33 | "Bad argument for '%s'. Malformed time string. GNUNET_STRINGS_fancy_time_to_absolute returned %d", | ||
34 | arg_name, | ||
35 | err); | ||
36 | }; | ||
37 | return NULL; | ||
38 | }; | ||
39 | case DBUS_TYPE_UINT64: | ||
40 | dbus_message_iter_get_basic (&iter_sub, &value->abs_value_us); | ||
41 | return NULL; | ||
42 | default: | ||
43 | return dbus_message_new_error_printf ( | ||
44 | message, | ||
45 | DBUS_ERROR_INVALID_ARGS, | ||
46 | "Bad argument for '%s'. Variant must contain a time encoded as a human readable string or a uint64 representing the number of microseconds since epoch. Contains %s.", | ||
47 | arg_name, | ||
48 | GNUNET_DBUS_signature_typecode_to_string (arg_type)); | ||
49 | }; | ||
50 | }; | ||
51 | |||
52 | |||
diff --git a/src/lib/util/gnunet_time_dbus_lib_push.c b/src/lib/util/gnunet_time_dbus_lib_push.c new file mode 100644 index 0000000..a618278 --- /dev/null +++ b/src/lib/util/gnunet_time_dbus_lib_push.c | |||
@@ -0,0 +1,61 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_strings_lib.h> | ||
6 | |||
7 | #include "gnunet_time_dbus_lib.h" | ||
8 | |||
9 | #define LOG(kind, ...) GNUNET_log_from (kind, "time-dbus-push", __VA_ARGS__) | ||
10 | |||
11 | void | ||
12 | GNUNET_TIME_DBUS_push_absolute ( | ||
13 | DBusMessage *message, | ||
14 | DBusMessageIter *iter, | ||
15 | const struct GNUNET_TIME_Absolute *value) | ||
16 | { | ||
17 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing absolute time\n"); | ||
18 | DBusMessageIter iter_sub; | ||
19 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
20 | { | ||
21 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Encoding time as string\n"); | ||
22 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
23 | const char *stringified = GNUNET_STRINGS_absolute_time_to_string (*value); | ||
24 | GNUNET_DBUS_push_string (message, &iter_sub, &stringified); | ||
25 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
26 | } | ||
27 | else | ||
28 | { | ||
29 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Encoding time as uint64\n"); | ||
30 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_UINT64); | ||
31 | GNUNET_DBUS_push_uint64 (message, &iter_sub, &value->abs_value_us); | ||
32 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | void | ||
37 | GNUNET_TIME_DBUS_push_relative ( | ||
38 | DBusMessage *message, | ||
39 | DBusMessageIter *iter, | ||
40 | const struct GNUNET_TIME_Relative *value) | ||
41 | { | ||
42 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Pushing relative time\n"); | ||
43 | DBusMessageIter iter_sub; | ||
44 | if (GNUNET_DBUS_message_get_pretty (message)) | ||
45 | { | ||
46 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Encoding time as string\n"); | ||
47 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_STRING); | ||
48 | const char *stringified = GNUNET_STRINGS_relative_time_to_string (*value, 0); | ||
49 | GNUNET_DBUS_push_string (message, &iter_sub, &stringified); | ||
50 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
51 | } | ||
52 | else | ||
53 | { | ||
54 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Encoding time as uint64\n"); | ||
55 | GNUNET_DBUS_push_open_variant (message, iter, &iter_sub, GNUNET_DBUS_SIGNATURE_UINT64); | ||
56 | GNUNET_DBUS_push_uint64 (message, &iter_sub, &value->rel_value_us); | ||
57 | GNUNET_DBUS_push_close_variant (message, iter, &iter_sub); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | |||
diff --git a/src/services/Makefile.am b/src/services/Makefile.am new file mode 100644 index 0000000..27c2372 --- /dev/null +++ b/src/services/Makefile.am | |||
@@ -0,0 +1,31 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CFLAGS = \ | ||
3 | -I$(top_builddir)/src/lib/include | ||
4 | |||
5 | bin_PROGRAMS = \ | ||
6 | gnunet-service-gns-dbus \ | ||
7 | gnunet-service-dht-dbus | ||
8 | |||
9 | gnunet_service_gns_dbus_SOURCES = \ | ||
10 | gnunet-service-gns-dbus.c | ||
11 | |||
12 | gnunet_service_gns_dbus_LDADD = \ | ||
13 | $(top_builddir)/src/lib/common/libgnunetdbus.la \ | ||
14 | $(top_builddir)/src/lib/util/libgnunettimedbus.la \ | ||
15 | $(top_builddir)/src/lib/util/libgnunetcryptodbus.la \ | ||
16 | $(top_builddir)/src/lib/gnsrecord/libgnunetgnsrecorddbus.la \ | ||
17 | -lgnunetgns \ | ||
18 | -lgnunetutil | ||
19 | |||
20 | gnunet_service_dht_dbus_SOURCES = \ | ||
21 | gnunet-service-dht-dbus.c | ||
22 | |||
23 | gnunet_service_dht_dbus_LDADD = \ | ||
24 | $(top_builddir)/src/lib/common/libgnunetdbus.la \ | ||
25 | $(top_builddir)/src/lib/util/libgnunettimedbus.la \ | ||
26 | $(top_builddir)/src/lib/util/libgnunetcryptodbus.la \ | ||
27 | $(top_builddir)/src/lib/dht/libgnunetdhtdbus.la \ | ||
28 | $(top_builddir)/src/lib/block/libgnunetblockdbus.la \ | ||
29 | -lgnunetdht \ | ||
30 | -lgnunetutil | ||
31 | |||
diff --git a/src/services/gnunet-service-dht-dbus.c b/src/services/gnunet-service-dht-dbus.c new file mode 100644 index 0000000..4b47be7 --- /dev/null +++ b/src/services/gnunet-service-dht-dbus.c | |||
@@ -0,0 +1,612 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_configuration_lib.h> | ||
6 | #include <gnunet/gnunet_getopt_lib.h> | ||
7 | #include <gnunet/gnunet_strings_lib.h> | ||
8 | #include <gnunet/gnunet_program_lib.h> | ||
9 | #include <gnunet/gnunet_dht_service.h> | ||
10 | |||
11 | #include "gnunet_dbus_lib.h" | ||
12 | #include "gnunet_dht_dbus_lib.h" | ||
13 | #include "gnunet_block_dbus_lib.h" | ||
14 | #include "gnunet_time_dbus_lib.h" | ||
15 | |||
16 | #define LOG(kind, ...) GNUNET_log_from (kind, "dht-dbus", __VA_ARGS__) | ||
17 | |||
18 | struct GetRequest | ||
19 | { | ||
20 | struct GNUNET_DBUS_Client *client; | ||
21 | struct GNUNET_DHT_GetHandle *handle; | ||
22 | bool pretty; | ||
23 | }; | ||
24 | |||
25 | struct ClientData | ||
26 | { | ||
27 | struct GNUNET_DBUS_ObjectIterator *gets_front; | ||
28 | struct GNUNET_DBUS_ObjectIterator *gets_back; | ||
29 | struct GNUNET_DHT_Handle *dht_handle; | ||
30 | }; | ||
31 | |||
32 | static struct GNUNET_DBUS_Service *gbl_dht_service; | ||
33 | static struct GNUNET_DBUS_Interface *gbl_dht_interface; | ||
34 | static struct GNUNET_DBUS_Method *gbl_dht_put_method; | ||
35 | static struct GNUNET_DBUS_Method *gbl_dht_get_start_method; | ||
36 | static struct GNUNET_DBUS_Object *gbl_dht_get_object; | ||
37 | static struct GNUNET_DBUS_Interface *gbl_dht_get_request_interface; | ||
38 | static struct GNUNET_DBUS_Method | ||
39 | *gbl_dht_get_request_filter_known_results_method; | ||
40 | static struct GNUNET_DBUS_Method *gbl_dht_get_request_stop_method; | ||
41 | static struct GNUNET_DBUS_Signal *gbl_dht_get_request_result_signal; | ||
42 | |||
43 | static void | ||
44 | put_return ( | ||
45 | void *cls, | ||
46 | int success) | ||
47 | { | ||
48 | struct GNUNET_DBUS_MethodContext *mc = | ||
49 | (struct GNUNET_DBUS_MethodContext *)cls; | ||
50 | unsigned msg_serial = dbus_message_get_serial (mc->message); | ||
51 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
52 | "Received reply from DHT. Method call id %u\n", | ||
53 | msg_serial); | ||
54 | DBusMessage *reply; | ||
55 | switch (success) | ||
56 | { | ||
57 | case GNUNET_OK: | ||
58 | reply = GNUNET_DBUS_method_context_create_reply (mc); | ||
59 | break; | ||
60 | case GNUNET_NO: | ||
61 | reply = dbus_message_new_error ( | ||
62 | mc->message, | ||
63 | DBUS_ERROR_FAILED, | ||
64 | "DHT service timed out."); | ||
65 | break; | ||
66 | case GNUNET_SYSERR: | ||
67 | reply = dbus_message_new_error ( | ||
68 | mc->message, | ||
69 | DBUS_ERROR_FAILED, | ||
70 | "DHT DBus proxy was disconnected from DHT service."); | ||
71 | break; | ||
72 | default: | ||
73 | reply = dbus_message_new_error_printf ( | ||
74 | mc->message, | ||
75 | DBUS_ERROR_FAILED, | ||
76 | "Unabled to interpret response from DHT service." | ||
77 | "Service returned code %d.", | ||
78 | success); | ||
79 | }; | ||
80 | |||
81 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
82 | GNUNET_DBUS_method_context_unref (mc); | ||
83 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
84 | "Received reply from DHT. Method call id %u\n", | ||
85 | msg_serial); | ||
86 | }; | ||
87 | |||
88 | static void | ||
89 | put ( | ||
90 | struct GNUNET_DBUS_MethodContext *mc) | ||
91 | { | ||
92 | struct GNUNET_HashCode key; | ||
93 | uint32_t desired_replication_level; | ||
94 | enum GNUNET_DHT_RouteOption options; | ||
95 | enum GNUNET_BLOCK_Type type; | ||
96 | int size; | ||
97 | const void *data; | ||
98 | struct GNUNET_TIME_Absolute expiry; | ||
99 | |||
100 | unsigned msg_serial = dbus_message_get_serial (mc->message); | ||
101 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
102 | "Recieved put from dbus. Method call id %u\n", | ||
103 | msg_serial); | ||
104 | |||
105 | DBusMessage *message = mc->message; | ||
106 | DBusMessageIter iter; | ||
107 | dbus_message_iter_init (message, &iter); | ||
108 | |||
109 | DBusMessage *reply = NULL; | ||
110 | reply = reply ? reply : GNUNET_DBUS_pop_hashcode ( | ||
111 | message, &iter, | ||
112 | "key", | ||
113 | &key); | ||
114 | reply = reply ? reply : GNUNET_DBUS_pop_uint32 ( | ||
115 | message, &iter, | ||
116 | "desired_replication_level", | ||
117 | &desired_replication_level); | ||
118 | reply = reply ? reply : GNUNET_DHT_DBUS_pop_route_option ( | ||
119 | message, &iter, | ||
120 | "options", | ||
121 | &options); | ||
122 | reply = reply ? reply : GNUNET_BLOCK_DBUS_pop_type ( | ||
123 | message, &iter, | ||
124 | "type", | ||
125 | &type); | ||
126 | reply = reply ? reply : GNUNET_DBUS_pop_byte_array ( | ||
127 | message, &iter, | ||
128 | "data", | ||
129 | (const unsigned char **)&data, &size); | ||
130 | reply = reply ? reply : GNUNET_TIME_DBUS_pop_absolute ( | ||
131 | message, &iter, | ||
132 | "expiry", | ||
133 | &expiry); | ||
134 | if (reply) | ||
135 | { | ||
136 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
137 | return; | ||
138 | }; | ||
139 | |||
140 | GNUNET_DBUS_method_context_ref (mc); | ||
141 | struct ClientData *cd = GNUNET_DBUS_client_get_data (mc->client); | ||
142 | struct GNUNET_DHT_Handle *handle = cd->dht_handle; | ||
143 | |||
144 | GNUNET_DHT_put ( | ||
145 | handle, | ||
146 | &key, | ||
147 | desired_replication_level, | ||
148 | options, | ||
149 | type, | ||
150 | size, | ||
151 | data, | ||
152 | expiry, | ||
153 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100), | ||
154 | put_return, | ||
155 | mc); | ||
156 | |||
157 | LOG ( | ||
158 | GNUNET_ERROR_TYPE_DEBUG, | ||
159 | "Forwarded put to dht. Method call id %u\n", | ||
160 | msg_serial); | ||
161 | }; | ||
162 | |||
163 | static void | ||
164 | get_filter_known_results ( | ||
165 | struct GNUNET_DBUS_MethodContext *mc) | ||
166 | { | ||
167 | struct GNUNET_HashCode *results; | ||
168 | size_t results_len; | ||
169 | |||
170 | DBusMessage *message = mc->message; | ||
171 | DBusMessageIter iter; | ||
172 | DBusMessageIter iter_sub; | ||
173 | dbus_message_iter_init (message, &iter); | ||
174 | |||
175 | DBusMessage *reply = NULL; | ||
176 | reply = GNUNET_DBUS_pop_enter_array (message, &iter, &iter_sub, | ||
177 | "results", | ||
178 | &results_len); | ||
179 | if (reply) | ||
180 | { | ||
181 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
182 | return ; | ||
183 | }; | ||
184 | |||
185 | results = GNUNET_malloc (sizeof (struct GNUNET_HashCode) * results_len); | ||
186 | size_t i; | ||
187 | for (i = 0; i < results_len && ! results ; i++) | ||
188 | reply = GNUNET_DBUS_pop_hashcode (message, &iter_sub, | ||
189 | "result", | ||
190 | results + i); | ||
191 | if(reply) | ||
192 | { | ||
193 | GNUNET_free (results); | ||
194 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
195 | return; | ||
196 | }; | ||
197 | |||
198 | struct GetRequest *get_request = GNUNET_DBUS_object_get_data (mc->object); | ||
199 | struct GNUNET_DHT_GetHandle *handle = get_request->handle; | ||
200 | |||
201 | GNUNET_DHT_get_filter_known_results (handle, (unsigned)results_len, results); | ||
202 | GNUNET_free (results); | ||
203 | |||
204 | reply = GNUNET_DBUS_method_context_create_reply (mc); | ||
205 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
206 | } | ||
207 | |||
208 | static void | ||
209 | get_stop ( | ||
210 | struct GNUNET_DBUS_MethodContext *mc) | ||
211 | { | ||
212 | struct GNUNET_DBUS_Object *object = mc->object; | ||
213 | struct GetRequest *get_request = GNUNET_DBUS_object_get_data (object); | ||
214 | struct GNUNET_DHT_GetHandle *handle = get_request->handle; | ||
215 | |||
216 | GNUNET_DHT_get_stop (handle); | ||
217 | |||
218 | struct GNUNET_DBUS_ObjectIterator *obj_it = | ||
219 | GNUNET_DBUS_object_iterate_subobjects (gbl_dht_get_object); | ||
220 | while (obj_it) | ||
221 | { | ||
222 | if (obj_it->object == object) | ||
223 | { | ||
224 | GNUNET_DBUS_object_remove_subobject (gbl_dht_get_object, obj_it); | ||
225 | break; | ||
226 | } | ||
227 | obj_it = obj_it->next; | ||
228 | }; | ||
229 | if (obj_it) | ||
230 | { | ||
231 | GNUNET_DBUS_client_unref (get_request->client); | ||
232 | GNUNET_free (get_request); | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
237 | "Tried to stop request that does not exist\n"); | ||
238 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
239 | " name == %s\n", | ||
240 | GNUNET_DBUS_object_get_name (object)); | ||
241 | } | ||
242 | |||
243 | DBusMessage *reply = GNUNET_DBUS_method_context_create_reply (mc); | ||
244 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
245 | } | ||
246 | |||
247 | static void | ||
248 | get_iter_return ( | ||
249 | void *cls, | ||
250 | struct GNUNET_TIME_Absolute expiry, | ||
251 | const struct GNUNET_HashCode *key, | ||
252 | const struct GNUNET_PeerIdentity *get_path, | ||
253 | unsigned get_path_len, | ||
254 | const struct GNUNET_PeerIdentity *put_path, | ||
255 | unsigned put_path_len, | ||
256 | enum GNUNET_BLOCK_Type type, | ||
257 | size_t size, | ||
258 | const void *data) | ||
259 | { | ||
260 | unsigned i; | ||
261 | struct GNUNET_DBUS_Object *request_object = (struct GNUNET_DBUS_Object *)cls; | ||
262 | struct GetRequest *get_request = | ||
263 | (struct GetRequest *)GNUNET_DBUS_object_get_data (request_object); | ||
264 | struct GNUNET_DBUS_Client *client = get_request->client; | ||
265 | struct GNUNET_DBUS_ObjectPath *path = GNUNET_DBUS_object_path_create ( | ||
266 | gbl_dht_service, | ||
267 | gbl_dht_get_object, | ||
268 | request_object, | ||
269 | NULL); | ||
270 | |||
271 | DBusMessage *message = GNUNET_DBUS_signal_spawn_unicast ( | ||
272 | gbl_dht_get_request_result_signal, | ||
273 | path, | ||
274 | gbl_dht_get_request_interface, | ||
275 | client, | ||
276 | get_request->pretty); | ||
277 | |||
278 | GNUNET_DBUS_object_path_unref (path); | ||
279 | |||
280 | DBusMessageIter message_iter; | ||
281 | DBusMessageIter message_iter_sub; | ||
282 | dbus_message_iter_init_append (message, &message_iter); | ||
283 | |||
284 | GNUNET_TIME_DBUS_push_absolute (message, &message_iter, &expiry); | ||
285 | GNUNET_DBUS_push_hashcode (message, &message_iter, key); | ||
286 | GNUNET_DBUS_push_open_array (message, &message_iter, &message_iter_sub, | ||
287 | GNUNET_DBUS_SIGNATURE_PEER_IDENTITY); | ||
288 | for (i = 0; i < get_path_len; i++) | ||
289 | { | ||
290 | GNUNET_DBUS_push_peer_identity (message, &message_iter_sub, get_path + i); | ||
291 | } | ||
292 | GNUNET_DBUS_push_close_array (message, &message_iter, &message_iter_sub); | ||
293 | GNUNET_DBUS_push_open_array (message, &message_iter, &message_iter_sub, | ||
294 | GNUNET_DBUS_SIGNATURE_PEER_IDENTITY); | ||
295 | for (i = 0; i < put_path_len; i++) | ||
296 | { | ||
297 | GNUNET_DBUS_push_peer_identity (message, &message_iter_sub, put_path + i); | ||
298 | } | ||
299 | GNUNET_DBUS_push_close_array (message, &message_iter, &message_iter_sub); | ||
300 | GNUNET_BLOCK_DBUS_push_type (message, &message_iter, &type); | ||
301 | GNUNET_DBUS_push_byte_array (message, &message_iter, data, size); | ||
302 | |||
303 | GNUNET_DBUS_service_send (gbl_dht_service, message); | ||
304 | } | ||
305 | |||
306 | static void | ||
307 | get_start ( | ||
308 | struct GNUNET_DBUS_MethodContext *mc) | ||
309 | { | ||
310 | enum GNUNET_BLOCK_Type type; | ||
311 | struct GNUNET_HashCode key; | ||
312 | uint32_t desired_replication_level; | ||
313 | enum GNUNET_DHT_RouteOption options; | ||
314 | |||
315 | unsigned msg_serial = dbus_message_get_serial (mc->message); | ||
316 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Recieved get_start from dbus. Method call id %u\n", msg_serial); | ||
317 | |||
318 | DBusMessage *message = mc->message; | ||
319 | DBusMessageIter iter; | ||
320 | dbus_message_iter_init (message, &iter); | ||
321 | |||
322 | DBusMessage *reply = NULL; | ||
323 | reply = reply ? reply : GNUNET_BLOCK_DBUS_pop_type ( | ||
324 | message, &iter, | ||
325 | "type", | ||
326 | &type); | ||
327 | reply = reply ? reply : GNUNET_DBUS_pop_hashcode ( | ||
328 | message, &iter, | ||
329 | "key", | ||
330 | &key); | ||
331 | reply = reply ? reply : GNUNET_DBUS_pop_uint32 ( | ||
332 | message, &iter, | ||
333 | "desired_replication_level", | ||
334 | &desired_replication_level); | ||
335 | reply = reply ? reply : GNUNET_DHT_DBUS_pop_route_option ( | ||
336 | message, &iter, | ||
337 | "options", | ||
338 | &options); | ||
339 | if (reply) | ||
340 | { | ||
341 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
342 | return; | ||
343 | }; | ||
344 | //if (GNUNET_DBUS_message_get_pretty_encoded (message)) | ||
345 | //GNUNET_DBUS_client_set_prefers_pretty_encodings (mc->client, true); | ||
346 | |||
347 | GNUNET_DBUS_method_context_ref (mc); | ||
348 | struct ClientData *cd = GNUNET_DBUS_client_get_data (mc->client); | ||
349 | struct GNUNET_DHT_Handle *handle = cd->dht_handle; | ||
350 | |||
351 | struct GetRequest *get_request = GNUNET_new (struct GetRequest); | ||
352 | get_request->client = mc->client; | ||
353 | GNUNET_DBUS_client_ref (mc->client); | ||
354 | get_request->pretty = GNUNET_DBUS_message_get_pretty (message); | ||
355 | |||
356 | struct GNUNET_DBUS_Object *request_object = | ||
357 | GNUNET_DBUS_object_create_uniquely_named_subobject (gbl_dht_get_object, | ||
358 | get_request); | ||
359 | GNUNET_DBUS_object_add_interface (request_object, | ||
360 | GNUNET_DBUS_interface_introspectable ()); | ||
361 | GNUNET_DBUS_object_add_interface (request_object, | ||
362 | gbl_dht_get_request_interface); | ||
363 | |||
364 | struct GNUNET_DBUS_ObjectPath *path = | ||
365 | GNUNET_DBUS_object_path_create (gbl_dht_service, | ||
366 | gbl_dht_get_object, | ||
367 | request_object, | ||
368 | NULL); | ||
369 | |||
370 | reply = GNUNET_DBUS_method_context_create_reply (mc); | ||
371 | DBusMessageIter reply_iter; | ||
372 | dbus_message_iter_init_append (reply, &reply_iter); | ||
373 | GNUNET_DBUS_push_object_path (reply, &reply_iter, path); | ||
374 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
375 | |||
376 | struct GNUNET_DBUS_ObjectIterator *obj_it = | ||
377 | GNUNET_new (struct GNUNET_DBUS_ObjectIterator); | ||
378 | obj_it->object = request_object; | ||
379 | GNUNET_CONTAINER_DLL_insert (cd->gets_front, | ||
380 | cd->gets_back, | ||
381 | obj_it); | ||
382 | |||
383 | get_request->handle = GNUNET_DHT_get_start ( | ||
384 | handle, | ||
385 | type, | ||
386 | &key, | ||
387 | desired_replication_level, | ||
388 | options, | ||
389 | NULL, | ||
390 | 0, | ||
391 | get_iter_return, | ||
392 | request_object); | ||
393 | }; | ||
394 | |||
395 | static void | ||
396 | client_connects ( | ||
397 | struct GNUNET_DBUS_Service *service, | ||
398 | struct GNUNET_DBUS_Client *client) | ||
399 | { | ||
400 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
401 | "Creating dht client for %s\n", | ||
402 | GNUNET_DBUS_client_get_unique_name (client)); | ||
403 | const struct GNUNET_CONFIGURATION_Handle *cfg = | ||
404 | GNUNET_DBUS_service_get_config (service); | ||
405 | struct ClientData *cd = GNUNET_new (struct ClientData); | ||
406 | cd->dht_handle = GNUNET_DHT_connect (cfg, 32); | ||
407 | cd->gets_front = NULL; | ||
408 | cd->gets_back = NULL; | ||
409 | GNUNET_DBUS_client_set_data (client, cd); | ||
410 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
411 | "Finished creating DHT client for %s\n", | ||
412 | GNUNET_DBUS_client_get_unique_name (client)); | ||
413 | }; | ||
414 | |||
415 | static void | ||
416 | client_disconnects ( | ||
417 | struct GNUNET_DBUS_Service *service, | ||
418 | struct GNUNET_DBUS_Client *client) | ||
419 | { | ||
420 | struct ClientData *cd = GNUNET_DBUS_client_get_data (client); | ||
421 | struct GNUNET_DBUS_ObjectIterator *obj_it = cd->gets_front; | ||
422 | while (obj_it) | ||
423 | { | ||
424 | struct GNUNET_DBUS_ObjectIterator *next = obj_it->next; | ||
425 | struct GNUNET_DBUS_Object *object = obj_it->object; | ||
426 | struct GetRequest *request = GNUNET_DBUS_object_get_data (object); | ||
427 | |||
428 | GNUNET_DHT_get_stop (request->handle); | ||
429 | GNUNET_free (request); | ||
430 | GNUNET_DBUS_object_remove_subobject (gbl_dht_get_object, obj_it); | ||
431 | GNUNET_free (obj_it); | ||
432 | obj_it = next; | ||
433 | }; | ||
434 | GNUNET_DHT_disconnect (cd->dht_handle); | ||
435 | GNUNET_free (cd); | ||
436 | }; | ||
437 | |||
438 | static void | ||
439 | shutdown_task ( | ||
440 | void *cls, | ||
441 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
442 | { | ||
443 | (void)cls; | ||
444 | (void)tc; | ||
445 | |||
446 | GNUNET_DBUS_service_unref (gbl_dht_service); | ||
447 | |||
448 | LOG (GNUNET_ERROR_TYPE_INFO, "Exiting.\n"); | ||
449 | }; | ||
450 | |||
451 | static void | ||
452 | run ( | ||
453 | void *cls, | ||
454 | char *const *args, | ||
455 | const char *configfile, | ||
456 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
457 | { | ||
458 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Running.\n"); | ||
459 | |||
460 | gbl_dht_service = GNUNET_DBUS_service_create (cfg, "dht"); | ||
461 | if (! gbl_dht_service) | ||
462 | { | ||
463 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create dht service.\n"); | ||
464 | GNUNET_abort_ (); | ||
465 | }; | ||
466 | GNUNET_DBUS_service_set_client_handlers (gbl_dht_service, | ||
467 | client_connects, | ||
468 | client_disconnects); | ||
469 | |||
470 | struct GNUNET_DBUS_Object *root_object = | ||
471 | GNUNET_DBUS_service_get_root_object (gbl_dht_service); | ||
472 | |||
473 | gbl_dht_interface = GNUNET_DBUS_interface_create ("gnu.gnunet.dht"); | ||
474 | GNUNET_DBUS_object_add_interface (root_object, | ||
475 | GNUNET_DBUS_interface_introspectable ()); | ||
476 | GNUNET_DBUS_object_add_interface (root_object, | ||
477 | gbl_dht_interface); | ||
478 | |||
479 | gbl_dht_put_method = GNUNET_DBUS_method_create ("put", put); | ||
480 | GNUNET_DBUS_interface_add_method (gbl_dht_interface, gbl_dht_put_method); | ||
481 | GNUNET_DBUS_method_add_arg (gbl_dht_put_method, | ||
482 | "key", | ||
483 | GNUNET_DBUS_SIGNATURE_HASHCODE); | ||
484 | GNUNET_DBUS_method_add_arg (gbl_dht_put_method, | ||
485 | "desired_replication_level", | ||
486 | GNUNET_DBUS_SIGNATURE_UINT32); | ||
487 | GNUNET_DBUS_method_add_arg (gbl_dht_put_method, | ||
488 | "options", | ||
489 | GNUNET_DHT_DBUS_SIGNATURE_ROUTE_OPTION); | ||
490 | GNUNET_DBUS_method_add_arg (gbl_dht_put_method, | ||
491 | "type", | ||
492 | GNUNET_BLOCK_DBUS_SIGNATURE_TYPE); | ||
493 | GNUNET_DBUS_method_add_arg (gbl_dht_put_method, | ||
494 | "data", | ||
495 | GNUNET_DBUS_SIGNATURE_ARRAY ( | ||
496 | GNUNET_DBUS_SIGNATURE_BYTE)); | ||
497 | GNUNET_DBUS_method_add_arg (gbl_dht_put_method, | ||
498 | "expiry", | ||
499 | GNUNET_TIME_DBUS_SIGNATURE_ABSOLUTE); | ||
500 | |||
501 | gbl_dht_get_start_method = GNUNET_DBUS_method_create ("get_start", | ||
502 | get_start); | ||
503 | GNUNET_DBUS_interface_add_method (gbl_dht_interface, | ||
504 | gbl_dht_get_start_method); | ||
505 | GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method, | ||
506 | "type", | ||
507 | GNUNET_BLOCK_DBUS_SIGNATURE_TYPE); | ||
508 | GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method, | ||
509 | "key", | ||
510 | GNUNET_DBUS_SIGNATURE_HASHCODE); | ||
511 | GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method, | ||
512 | "desired_replication_level", | ||
513 | GNUNET_DBUS_SIGNATURE_UINT32); | ||
514 | GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method, | ||
515 | "options", | ||
516 | GNUNET_DHT_DBUS_SIGNATURE_ROUTE_OPTION); | ||
517 | GNUNET_DBUS_method_add_return_arg (gbl_dht_get_start_method, | ||
518 | "request_object", | ||
519 | GNUNET_DBUS_SIGNATURE_OBJECT_PATH); | ||
520 | |||
521 | gbl_dht_get_object = GNUNET_DBUS_object_create ("get", NULL); | ||
522 | GNUNET_DBUS_object_add_subobject (root_object, gbl_dht_get_object); | ||
523 | GNUNET_DBUS_object_add_interface (gbl_dht_get_object, | ||
524 | GNUNET_DBUS_interface_introspectable ()); | ||
525 | |||
526 | gbl_dht_get_request_interface = | ||
527 | GNUNET_DBUS_interface_create ("gnu.gnunet.dht.get"); | ||
528 | |||
529 | gbl_dht_get_request_filter_known_results_method = | ||
530 | GNUNET_DBUS_method_create ("filter_known_results", | ||
531 | get_filter_known_results); | ||
532 | GNUNET_DBUS_interface_add_method ( | ||
533 | gbl_dht_get_request_interface, | ||
534 | gbl_dht_get_request_filter_known_results_method); | ||
535 | GNUNET_DBUS_method_add_arg (gbl_dht_get_request_filter_known_results_method, | ||
536 | "results", | ||
537 | GNUNET_DBUS_SIGNATURE_ARRAY ( | ||
538 | GNUNET_DBUS_SIGNATURE_HASHCODE)); | ||
539 | |||
540 | gbl_dht_get_request_stop_method = GNUNET_DBUS_method_create ("stop", | ||
541 | get_stop); | ||
542 | GNUNET_DBUS_interface_add_method (gbl_dht_get_request_interface, | ||
543 | gbl_dht_get_request_stop_method); | ||
544 | |||
545 | gbl_dht_get_request_result_signal = GNUNET_DBUS_signal_create ("result"); | ||
546 | GNUNET_DBUS_interface_add_signal (gbl_dht_get_request_interface, | ||
547 | gbl_dht_get_request_result_signal); | ||
548 | GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal, | ||
549 | "expiry", | ||
550 | GNUNET_TIME_DBUS_SIGNATURE_ABSOLUTE); | ||
551 | GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal, | ||
552 | "key", | ||
553 | GNUNET_DBUS_SIGNATURE_HASHCODE); | ||
554 | GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal, | ||
555 | "get_path", | ||
556 | GNUNET_DBUS_SIGNATURE_ARRAY ( | ||
557 | GNUNET_DBUS_SIGNATURE_PEER_IDENTITY)); | ||
558 | GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal, | ||
559 | "put_path", | ||
560 | GNUNET_DBUS_SIGNATURE_ARRAY ( | ||
561 | GNUNET_DBUS_SIGNATURE_PEER_IDENTITY)); | ||
562 | GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal, | ||
563 | "type", | ||
564 | GNUNET_BLOCK_DBUS_SIGNATURE_TYPE); | ||
565 | GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal, | ||
566 | "data", | ||
567 | GNUNET_DBUS_SIGNATURE_ARRAY ( | ||
568 | GNUNET_DBUS_SIGNATURE_BYTE)); | ||
569 | |||
570 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
571 | shutdown_task, NULL); | ||
572 | }; | ||
573 | |||
574 | int | ||
575 | main ( | ||
576 | int argc, | ||
577 | char *const *argv) | ||
578 | { | ||
579 | int ret; | ||
580 | |||
581 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
582 | GNUNET_GETOPT_OPTION_END | ||
583 | }; | ||
584 | static const char bin_name[] = "gnunet-service-dht-dbus [OPTIONS]"; | ||
585 | static const char bin_help[] = gettext_noop ("DBus proxy for gnunet-service-dht"); | ||
586 | |||
587 | ret = GNUNET_log_setup ("gnunet-service-dht-dbus", "DEBUG", NULL); | ||
588 | if (GNUNET_OK != ret) | ||
589 | { | ||
590 | fprintf (stderr, "ERROR: Failed to setup logging. GNUNET_log_setup returned %d\n", ret); | ||
591 | return 1; | ||
592 | } | ||
593 | |||
594 | ret = GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv); | ||
595 | if (GNUNET_OK != ret) | ||
596 | { | ||
597 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to parse command line options. GNUNET_STRINGS_get_utf8_args returned %d\n", ret); | ||
598 | return 1; | ||
599 | }; | ||
600 | |||
601 | ret = GNUNET_PROGRAM_run (argc, argv, bin_name, bin_help, options, run, NULL); | ||
602 | if (GNUNET_OK != ret) | ||
603 | { | ||
604 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to run program. GNUNET_PROGRAM_run returned %d\n", ret); | ||
605 | return 1; | ||
606 | }; | ||
607 | |||
608 | GNUNET_free ((void *)argv); | ||
609 | return 0; | ||
610 | }; | ||
611 | |||
612 | |||
diff --git a/src/services/gnunet-service-gns-dbus.c b/src/services/gnunet-service-gns-dbus.c new file mode 100644 index 0000000..29ac2f8 --- /dev/null +++ b/src/services/gnunet-service-gns-dbus.c | |||
@@ -0,0 +1,198 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_configuration_lib.h> | ||
6 | #include <gnunet/gnunet_getopt_lib.h> | ||
7 | #include <gnunet/gnunet_strings_lib.h> | ||
8 | #include <gnunet/gnunet_program_lib.h> | ||
9 | #include <gnunet/gnunet_gns_service.h> | ||
10 | |||
11 | #include "gnunet_dbus_lib.h" | ||
12 | #include "gnunet_crypto_dbus_lib.h" | ||
13 | #include "gnunet_gnsrecord_dbus_lib.h" | ||
14 | |||
15 | #define LOG(kind, ...) GNUNET_log_from (kind, "gns-dbus", __VA_ARGS__) | ||
16 | |||
17 | static void | ||
18 | lookup_return ( | ||
19 | void *cls, | ||
20 | uint32_t rd_count, | ||
21 | const struct GNUNET_GNSRECORD_Data *rd) | ||
22 | { | ||
23 | struct GNUNET_DBUS_MethodContext *mc = (struct GNUNET_DBUS_MethodContext *)cls; | ||
24 | unsigned msg_serial = dbus_message_get_serial (mc->message); | ||
25 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply from GNS. Method call id %u\n", msg_serial); | ||
26 | DBusMessage *reply = GNUNET_DBUS_method_context_create_reply (mc); | ||
27 | DBusMessageIter reply_iter; | ||
28 | dbus_message_iter_init_append (reply, &reply_iter); | ||
29 | |||
30 | DBusMessageIter reply_iter_sub; | ||
31 | GNUNET_DBUS_push_open_array (reply, &reply_iter, &reply_iter_sub, GNUNET_GNSRECORD_DBUS_SIGNATURE_DATA); | ||
32 | uint32_t i; | ||
33 | for (i = 0; i < rd_count; i++) | ||
34 | GNUNET_GNSRECORD_DBUS_push_data (reply, &reply_iter_sub, rd + i); | ||
35 | GNUNET_DBUS_push_close_array (reply, &reply_iter, &reply_iter_sub); | ||
36 | |||
37 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
38 | GNUNET_DBUS_method_context_unref (mc); | ||
39 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Forwarded reply to dbus. Method call id %u\n", msg_serial); | ||
40 | }; | ||
41 | |||
42 | #if 0 | ||
43 | static void | ||
44 | lookup_timeout ( | ||
45 | void *cls, | ||
46 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
47 | { | ||
48 | struct GNUNET_GNS_LookupRequest *lr = (struct GNUNET_GNS_LookupRequest *)cls; | ||
49 | GNUNET_G | ||
50 | } | ||
51 | #endif | ||
52 | |||
53 | static void | ||
54 | lookup ( | ||
55 | struct GNUNET_DBUS_MethodContext *mc) | ||
56 | { | ||
57 | const char *name; | ||
58 | struct GNUNET_CRYPTO_EcdsaPublicKey zone; | ||
59 | uint32_t type; | ||
60 | dbus_bool_t only_cached; | ||
61 | |||
62 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received lookup request from dbus. Method call id %u\n", dbus_message_get_serial (mc->message)); | ||
63 | |||
64 | DBusMessage *message = mc->message; | ||
65 | DBusMessageIter message_iter; | ||
66 | dbus_message_iter_init (message, &message_iter); | ||
67 | |||
68 | DBusMessage *reply = NULL; | ||
69 | reply = reply ? reply : GNUNET_DBUS_pop_string (message, &message_iter, "name", &name); | ||
70 | reply = reply ? reply : GNUNET_CRYPTO_DBUS_pop_ecdsa_public_key (message, &message_iter, "zone", &zone); | ||
71 | reply = reply ? reply : GNUNET_GNSRECORD_DBUS_pop_type (message, &message_iter, "type", &type); | ||
72 | reply = reply ? reply : GNUNET_DBUS_pop_boolean (message, &message_iter, "only_cached", &only_cached); | ||
73 | if (reply) | ||
74 | { | ||
75 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
76 | return; | ||
77 | }; | ||
78 | |||
79 | GNUNET_DBUS_method_context_ref (mc); | ||
80 | struct GNUNET_GNS_Handle *handle = GNUNET_DBUS_client_get_data (mc->client); | ||
81 | struct GNUNET_GNS_LookupRequest *lr = GNUNET_GNS_lookup ( | ||
82 | handle, | ||
83 | name, &zone, (int)type, (int)only_cached, NULL, | ||
84 | lookup_return, mc); | ||
85 | (void)lr; | ||
86 | |||
87 | //GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (500, GNUNET_TIME_UNIT_MILLISECONDS), | ||
88 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Forwarded lookup to GNS. Method call id %u\n", dbus_message_get_serial (mc->message)); | ||
89 | }; | ||
90 | |||
91 | static void | ||
92 | client_connects ( | ||
93 | struct GNUNET_DBUS_Service *service, | ||
94 | struct GNUNET_DBUS_Client *client) | ||
95 | { | ||
96 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating GNS client for %s\n", GNUNET_DBUS_client_get_unique_name (client)); | ||
97 | const struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_DBUS_service_get_config (service); | ||
98 | struct GNUNET_GNS_Handle *handle = GNUNET_GNS_connect (cfg); | ||
99 | GNUNET_DBUS_client_set_data (client, handle); | ||
100 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished creating GNS client for %s\n", GNUNET_DBUS_client_get_unique_name (client)); | ||
101 | }; | ||
102 | |||
103 | static void | ||
104 | client_disconnects ( | ||
105 | struct GNUNET_DBUS_Service *service, | ||
106 | struct GNUNET_DBUS_Client *client) | ||
107 | { | ||
108 | (void)service; | ||
109 | GNUNET_GNS_disconnect (GNUNET_DBUS_client_get_data (client)); | ||
110 | }; | ||
111 | |||
112 | static void | ||
113 | shutdown_task ( | ||
114 | void *cls, | ||
115 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
116 | { | ||
117 | (void)tc; | ||
118 | |||
119 | struct GNUNET_DBUS_Service *gns_service = (struct GNUNET_DBUS_Service *)cls; | ||
120 | GNUNET_DBUS_service_unref (gns_service); | ||
121 | |||
122 | LOG (GNUNET_ERROR_TYPE_INFO, "Exiting.\n"); | ||
123 | }; | ||
124 | |||
125 | static void | ||
126 | run ( | ||
127 | void *cls, | ||
128 | char *const *args, | ||
129 | const char *configfile, | ||
130 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
131 | { | ||
132 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Running.\n"); | ||
133 | |||
134 | struct GNUNET_DBUS_Service *gns_service = GNUNET_DBUS_service_create (cfg, "gns"); | ||
135 | if (! gns_service) | ||
136 | { | ||
137 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create gns service.\n"); | ||
138 | GNUNET_abort_ (); | ||
139 | }; | ||
140 | GNUNET_DBUS_service_set_client_handlers (gns_service, client_connects, client_disconnects); | ||
141 | |||
142 | struct GNUNET_DBUS_Object *gns_object = GNUNET_DBUS_service_get_root_object (gns_service); | ||
143 | |||
144 | struct GNUNET_DBUS_Interface *gns_interface = GNUNET_DBUS_interface_create ("gnu.gnunet.gns"); | ||
145 | GNUNET_DBUS_object_add_interface (gns_object, GNUNET_DBUS_interface_introspectable ()); | ||
146 | GNUNET_DBUS_object_add_interface (gns_object, gns_interface); | ||
147 | |||
148 | struct GNUNET_DBUS_Method *gns_method_lookup = GNUNET_DBUS_method_create ("lookup", lookup); | ||
149 | GNUNET_DBUS_interface_add_method (gns_interface, gns_method_lookup); | ||
150 | GNUNET_DBUS_method_add_arg (gns_method_lookup, "name", GNUNET_DBUS_SIGNATURE_STRING); | ||
151 | GNUNET_DBUS_method_add_arg (gns_method_lookup, "zone", GNUNET_CRYPTO_DBUS_SIGNATURE_ECDSA_PUBLIC_KEY); | ||
152 | GNUNET_DBUS_method_add_arg (gns_method_lookup, "type", GNUNET_GNSRECORD_DBUS_SIGNATURE_TYPE); | ||
153 | GNUNET_DBUS_method_add_arg (gns_method_lookup, "only_cached", GNUNET_DBUS_SIGNATURE_BOOLEAN); | ||
154 | |||
155 | GNUNET_DBUS_method_add_return_arg (gns_method_lookup, "records", GNUNET_DBUS_SIGNATURE_ARRAY (GNUNET_GNSRECORD_DBUS_SIGNATURE_DATA)); | ||
156 | |||
157 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, shutdown_task, gns_service); | ||
158 | }; | ||
159 | |||
160 | int | ||
161 | main ( | ||
162 | int argc, | ||
163 | char *const *argv) | ||
164 | { | ||
165 | int ret; | ||
166 | |||
167 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
168 | GNUNET_GETOPT_OPTION_END | ||
169 | }; | ||
170 | static const char bin_name[] = "gnunet-service-gns-dbus [OPTIONS]"; | ||
171 | static const char bin_help[] = gettext_noop ("DBus proxy for gnunet-service-gns"); | ||
172 | |||
173 | ret = GNUNET_log_setup ("gnunet-service-gns-dbus", "DEBUG", NULL); | ||
174 | if (GNUNET_OK != ret) | ||
175 | { | ||
176 | fprintf (stderr, "ERROR: Failed to setup logging. GNUNET_log_setup returned %d\n", ret); | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | ret = GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv); | ||
181 | if (GNUNET_OK != ret) | ||
182 | { | ||
183 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to parse command line options. GNUNET_STRINGS_get_utf8_args returned %d\n", ret); | ||
184 | return 1; | ||
185 | }; | ||
186 | |||
187 | ret = GNUNET_PROGRAM_run (argc, argv, bin_name, bin_help, options, run, NULL); | ||
188 | if (GNUNET_OK != ret) | ||
189 | { | ||
190 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to run program. GNUNET_PROGRAM_run returned %d\n", ret); | ||
191 | return 1; | ||
192 | }; | ||
193 | |||
194 | GNUNET_free ((void *)argv); | ||
195 | return 0; | ||
196 | }; | ||
197 | |||
198 | |||
diff --git a/src/services/gnunet-service-namecache-dbus.c b/src/services/gnunet-service-namecache-dbus.c new file mode 100644 index 0000000..7eded44 --- /dev/null +++ b/src/services/gnunet-service-namecache-dbus.c | |||
@@ -0,0 +1,158 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | #include <gnunet/platform.h> | ||
4 | #include <gnunet/gnunet_common.h> | ||
5 | #include <gnunet/gnunet_configuration_lib.h> | ||
6 | #include <gnunet/gnunet_getopt_lib.h> | ||
7 | #include <gnunet/gnunet_strings_lib.h> | ||
8 | #include <gnunet/gnunet_program_lib.h> | ||
9 | #include <gnunet/gnunet_namecache_service.h> | ||
10 | |||
11 | #include "gnunet_dbus_lib.h" | ||
12 | |||
13 | static void | ||
14 | block_cache_return ( | ||
15 | void *cls, | ||
16 | int32_t success, | ||
17 | const char *emsg) | ||
18 | { | ||
19 | struct GNUNET_DBUS_MethodContext *mc = (struct GNUNET_DBUS_MethodContext *)cls; | ||
20 | |||
21 | DBusMessage *message = mc->message; | ||
22 | DBusMessage *reply = dbus_message_new_method_return (message); | ||
23 | DBusMessageIter reply_iter; | ||
24 | dbus_message_iter_init_append (reply, &reply_iter); | ||
25 | GNUNET_DBUS_message_iter_push_int32 (&reply_iter, success); | ||
26 | GNUNET_DBUS_message_iter_push_string (&reply_iter, emsg); | ||
27 | |||
28 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
29 | GNUNET_DBUS_method_context_unref (mc); | ||
30 | }; | ||
31 | |||
32 | static void | ||
33 | block_cache ( | ||
34 | struct GNUNET_DBUS_MethodContext *mc) | ||
35 | { | ||
36 | struct GNUNET_GNSRECORD_Block block; | ||
37 | |||
38 | DBusMessage *dbus_message = mc->message; | ||
39 | DBusMessageIter iter; | ||
40 | dbus_message_iter_init (dbus_message, &iter); | ||
41 | DBusMessage *reply = GNUNET_DBUS_message_iter_pop_gnsrecord_block (dbus_message, &iter, "block", &block); | ||
42 | if (reply) | ||
43 | { | ||
44 | GNUNET_DBUS_method_context_send_reply (mc, reply); | ||
45 | return; | ||
46 | }; | ||
47 | |||
48 | GNUNET_DBUS_method_context_ref (mc); | ||
49 | struct GNUNET_NAMECACHE_Handle *handle = GNUNET_DBUS_client_get_data (mc->client); | ||
50 | GNUNET_NAMECACHE_block_cache (handle, &block, block_cache_return, mc); | ||
51 | }; | ||
52 | |||
53 | static void | ||
54 | client_connects ( | ||
55 | struct GNUNET_DBUS_Service *service, | ||
56 | struct GNUNET_DBUS_Client *client) | ||
57 | { | ||
58 | const struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_DBUS_service_get_config (service); | ||
59 | struct GNUNET_NAMECACHE_Handle *handle = GNUNET_NAMECACHE_connect (cfg); | ||
60 | GNUNET_DBUS_client_set_data (client, handle); | ||
61 | }; | ||
62 | |||
63 | static void | ||
64 | client_disconnects ( | ||
65 | struct GNUNET_DBUS_Service *service, | ||
66 | struct GNUNET_DBUS_Client *client) | ||
67 | { | ||
68 | (void)service; | ||
69 | GNUNET_NAMECACHE_disconnect (GNUNET_DBUS_client_get_data (client)); | ||
70 | }; | ||
71 | |||
72 | static void | ||
73 | shutdown_task ( | ||
74 | void *cls, | ||
75 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
76 | { | ||
77 | (void)tc; | ||
78 | |||
79 | struct GNUNET_DBUS_Service *gns_service = (struct GNUNET_DBUS_Service *)cls; | ||
80 | GNUNET_DBUS_service_destroy (gns_service); | ||
81 | |||
82 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Exiting.\n"); | ||
83 | }; | ||
84 | |||
85 | static void | ||
86 | run ( | ||
87 | void *cls, | ||
88 | char *const *args, | ||
89 | const char *configfile, | ||
90 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
91 | { | ||
92 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running.\n"); | ||
93 | |||
94 | struct GNUNET_DBUS_Service *namecache_service = GNUNET_DBUS_service_create (cfg, "namecache"); | ||
95 | GNUNET_DBUS_service_set_client_handlers (namecache_service, client_connects, client_disconnects); | ||
96 | |||
97 | struct GNUNET_DBUS_Object *namecache_object = GNUNET_DBUS_object_create ("/namecache", NULL); | ||
98 | int err = GNUNET_DBUS_service_add_object (namecache_service, namecache_object); | ||
99 | if (GNUNET_OK != err) | ||
100 | { | ||
101 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to add /namecache object. GNUNET_DBUS_service_add_object returned %d\n", err); | ||
102 | GNUNET_abort_ (); | ||
103 | }; | ||
104 | |||
105 | struct GNUNET_DBUS_Interface *namecache_interface = GNUNET_DBUS_interface_create ("gnu.gnunet.namecache"); | ||
106 | GNUNET_DBUS_object_add_interface (namecache_object, GNUNET_DBUS_interface_introspectable ()); | ||
107 | GNUNET_DBUS_object_add_interface (namecache_object, namecache_interface); | ||
108 | |||
109 | struct GNUNET_DBUS_Method *namecache_method_block_cache = GNUNET_DBUS_method_create ("block_cache", block_cache); | ||
110 | GNUNET_DBUS_interface_add_method (namecache_interface, namecache_method_block_cache); | ||
111 | GNUNET_DBUS_method_add_arg (namecache_method_block_cache, "block", GNUNET_DBUS_SIGNATURE_GNSRECORD_BLOCK); | ||
112 | |||
113 | GNUNET_DBUS_method_add_return_arg (namecache_method_block_cache, "success", GNUNET_DBUS_SIGNATURE_INT32); | ||
114 | GNUNET_DBUS_method_add_return_arg (namecache_method_block_cache, "error_msg", GNUNET_DBUS_SIGNATURE_STRING); | ||
115 | |||
116 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, shutdown_task, namecache_service); | ||
117 | }; | ||
118 | |||
119 | int | ||
120 | main ( | ||
121 | int argc, | ||
122 | char *const *argv) | ||
123 | { | ||
124 | int ret; | ||
125 | |||
126 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
127 | GNUNET_GETOPT_OPTION_END | ||
128 | }; | ||
129 | |||
130 | static const char bin_name[] = "gnunet-service-namecache-dbus [OPTIONS]"; | ||
131 | static const char bin_help[] = "DBus proxy for gnunet-service-namecache"; | ||
132 | |||
133 | ret = GNUNET_log_setup ("gnunet-service-namecache-dbus", "DEBUG", NULL); | ||
134 | if (GNUNET_OK != ret) | ||
135 | { | ||
136 | fprintf (stderr, "ERROR: Failed to setup logging. GNUNET_log_setup returned %d\n", ret); | ||
137 | return 1; | ||
138 | }; | ||
139 | |||
140 | ret = GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv); | ||
141 | if (GNUNET_OK != ret) | ||
142 | { | ||
143 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse command line options. GNUNET_STRINGS_get_utf8_args returned %d\n", ret); | ||
144 | return 1; | ||
145 | }; | ||
146 | |||
147 | ret = GNUNET_PROGRAM_run (argc, argv, bin_name, bin_help, options, run, NULL); | ||
148 | if (GNUNET_OK != ret) | ||
149 | { | ||
150 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to run program. GNUNET_PROGRAM_run returned %d\n", ret); | ||
151 | return 1; | ||
152 | }; | ||
153 | |||
154 | printf ("leaving main()\n"); | ||
155 | GNUNET_free ((void *)argv); | ||
156 | return 0; | ||
157 | } | ||
158 | |||