1 /* librepo - A library providing (libcURL like) API to downloading repository
2  * Copyright (C) 2012  Tomas Mlcoch
3  *
4  * Licensed under the GNU Lesser General Public License Version 2.1
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef __LR_HANDLE_H__
22 #define __LR_HANDLE_H__
23 
24 #include <glib.h>
25 
26 #include "result.h"
27 
28 G_BEGIN_DECLS
29 
30 /** \defgroup   handle    Librepo Handle
31  *  \addtogroup handle
32  *  @{
33  */
34 
35 /** Handle object containing configuration for repository metadata and
36  * package downloading.
37  */
38 typedef struct _LrHandle LrHandle;
39 
40 #ifdef WITH_ZCHUNK
41 /** Define LRO_SUPPORTS_CACHEDIR so clients can check for this feature at build
42  * time */
43 #define LRO_SUPPORTS_CACHEDIR
44 #endif /* WITH_ZCHUNK */
45 
46 /** LRO_FASTESTMIRRORMAXAGE default value */
47 #define LRO_FASTESTMIRRORMAXAGE_DEFAULT     2592000L // 30 days
48 
49 /** LRO_FASTESTMIRRORMAXAGE minimal allowed value */
50 #define LRO_FASTESTMIRRORMAXAGE_MIN         0L
51 
52 /** LRO_PROXYPORT default value */
53 #define LRO_PROXYPORT_DEFAULT               1080L
54 
55 /** LRO_PROXYTYPE default value */
56 #define LRO_PROXYTYPE_DEFAULT               LR_PROXY_HTTP
57 
58 /** LRO_MAXSPEED default value (0 == unlimited speed) */
59 #define LRO_MAXSPEED_DEFAULT                G_GINT64_CONSTANT(0)
60 
61 /** LRO_CONNECTTIMEOUT default value */
62 #define LRO_CONNECTTIMEOUT_DEFAULT          30L
63 
64 /** LRO_MAXMIRRORTRIES default value */
65 #define LRO_MAXMIRRORTRIES_DEFAULT          0L
66 
67 /** LRO_MAXMIRRORTRIES minimal allowed value */
68 #define LRO_MAXMIRRORTRIES_MIN              0L
69 
70 /** LRO_MAXPARALLELDOWNLOADS default value */
71 #define LRO_MAXPARALLELDOWNLOADS_DEFAULT    3L
72 
73 /** LRO_MAXPARALLELDOWNLOADS minimal allowed value */
74 #define LRO_MAXPARALLELDOWNLOADS_MIN        1L
75 
76 /** LRO_MAXPARALLELDOWNLOADS maximal allowed value */
77 #define LRO_MAXPARALLELDOWNLOADS_MAX        20L
78 
79 /** LRO_MAXDOWNLOADSPERMIRROR default value */
80 #define LRO_MAXDOWNLOADSPERMIRROR_DEFAULT   3L
81 
82 /** LRO_MAXDOWNLOADSPERMIRROR minimal allowed value */
83 #define LRO_MAXDOWNLOADSPERMIRROR_MIN       1L
84 
85 /** LRO_LOWSPEEDTIME minimal allowed value */
86 #define LRO_LOWSPEEDTIME_MIN                0L
87 
88 /** LRO_LOWSPEEDTIME default value */
89 #define LRO_LOWSPEEDTIME_DEFAULT            30L
90 
91 /** LRO_LOWSPEEDLIMIT minimal allowed value */
92 #define LRO_LOWSPEEDLIMIT_MIN               0L
93 
94 /** LRO_LOWSPEEDLIMIT default value */
95 #define LRO_LOWSPEEDLIMIT_DEFAULT           1000L
96 
97 /** LRO_IPRESOLVE default value */
98 #define LRO_IPRESOLVE_DEFAULT               LR_IPRESOLVE_WHATEVER
99 
100 /** LRO_ALLOWEDMIRRORFAILURES default value */
101 #define LRO_ALLOWEDMIRRORFAILURES_DEFAULT   4L
102 
103 /** LRO_ADAPTIVEMIRRORSORTING default value */
104 #define LRO_ADAPTIVEMIRRORSORTING_DEFAULT   1L
105 
106 /** LRO_GNUPGHOMEDIR default value */
107 #define LRO_GNUPGHOMEDIR_DEFAULT            NULL
108 
109 /** LRO_FASTESTMIRRORTIMEOUT default value */
110 #define LRO_FASTESTMIRRORTIMEOUT_DEFAULT    2.0
111 
112 /** LRO_OFFLINE default value */
113 #define LRO_OFFLINE_DEFAULT                 0L
114 
115 /** LRO_HTTPAUTHMETHODS default value*/
116 #define LRO_HTTPAUTHMETHODS_DEFAULT         LR_AUTH_BASIC
117 
118 /** LRO_PROXYAUTHMETHODS default value*/
119 #define LRO_PROXYAUTHMETHODS_DEFAULT        LR_AUTH_BASIC
120 
121 /** LRO_FTPUSEEPSV default value */
122 #define LRO_FTPUSEEPSV_DEFAULT              1L
123 
124 
125 /** Handle options for the ::lr_handle_setopt function. */
126 typedef enum {
127 
128     LRO_UPDATE,  /*!< (long 1 or 0)
129         Update existing repo in ::LrResult. Update means download missing
130         (previously omitted) metadata file(s). */
131 
132     LRO_URLS,  /*!< (char ** NULL-terminated)
133         List of base repo URLs */
134 
135     LRO_MIRRORLIST,  /*!< (char *)
136         Mirrorlist or metalink url.
137         This option is DEPRECATED!
138         Use LRO_MIRRORLISTURL or LRO_METALINKURL instead. */
139 
140     LRO_MIRRORLISTURL, /*!< (char *)
141         Mirrorlist url */
142 
143     LRO_METALINKURL, /*!< (char *)
144         Metalink url */
145 
146     LRO_LOCAL,  /*!< (long 1 or 0)
147         Do not duplicate local metadata, just locate the old one */
148 
149     LRO_HTTPAUTH,  /*!< (long 1 or 0)
150         Enable all supported method of HTTP authentification.
151         This option is DEPRECATED!
152         Use LRO_HTTPAUTHMETHODS */
153 
154     LRO_USERPWD,  /*!< (char *)
155         User and password for http authetification in format user:password */
156 
157     LRO_PROXY,  /*!< (char *)
158         Address of proxy server eg. "proxy-host.com:8080" */
159 
160     LRO_PROXYPORT,  /*!< (long)
161         Set port number for proxy separately. Default port is 1080. */
162 
163     LRO_PROXYTYPE,  /*!< (LrProxyType)
164         Type of the proxy used. */
165 
166     LRO_PROXYAUTH,  /*!< (long 1 or 0)
167         Enable all supported method for proxy authentification.
168         This option is DEPRECATED!
169         Use LRO_PROXYAUTHMETHODS */
170 
171     LRO_PROXYUSERPWD,  /*!< (char *)
172         User and password for proxy in format user:password */
173 
174     LRO_PROGRESSCB,  /*!< (LrProgressCb)
175         Progress callback */
176 
177     LRO_PROGRESSDATA,  /*!< (void *)
178         Progress callback user data */
179 
180     LRO_MAXSPEED,  /*!< (gint64)
181         Maximum download speed in bytes per second. Default is 0 = unlimited
182         download speed. */
183 
184     LRO_DESTDIR,  /*!< (char *)
185         Where to save downloaded files */
186 
187     LRO_REPOTYPE,  /*!< (LrRepotype)
188         Type of downloaded repo, currently only supported is LR_YUMREPO. */
189 
190     LRO_CONNECTTIMEOUT,  /*!< (long)
191         Max time in sec for connection phase. default timeout
192         is 300 seconds. */
193 
194     LRO_IGNOREMISSING,  /*!< (long 1 or 0)
195         If you want to localise (LRO_LOCAL is enabled) a incomplete local
196         repository (eg. only primary and filelists are present) you could
197         use LRO_YUMDLIST and specify only file that are present, or use this
198         option. */
199 
200     LRO_INTERRUPTIBLE,  /*!< (long 1 or 0)
201         If true, Librepo setups its own signal handler for SIGTERM and stops
202         downloading if SIGTERM is catched. In this case current operation
203         could return any kind of error code. Handle which operation was
204         interrupted should never be used again! */
205 
206     LRO_USERAGENT,  /*!< (char *)
207         String for  User-Agent: header in the http request sent to
208         the remote server */
209 
210     LRO_FETCHMIRRORS,  /*!< (long 1 or 0)
211         If true - do not download anything, except mirrorlist or metalink
212         (during lr_handle_perform()).*/
213 
214     LRO_MAXMIRRORTRIES,  /*!< (long)
215         If download fails try at most the specified number of mirrors.
216         0 means try all available mirrors. */
217 
218     LRO_MAXPARALLELDOWNLOADS,  /*!< (long)
219         Maximum number of parallel downloads. */
220 
221     LRO_MAXDOWNLOADSPERMIRROR,  /*!< (long)
222         Maximum number of parallel downloads per mirror. */
223 
224     LRO_VARSUB,  /*!< (LrUrlVars *)
225         Variables and its substitutions for repo URL.
226         [{"releasever", "f18"}], ...;
227         (e.g.: http://foo/$releasever => http://foo/f18)
228         LrUrlVars has to be constructed by the ::lr_urlvars_set() function.
229         After set the list to the handle, it has not to be freed! Handle
230         itself takes care about freeing the list. */
231 
232     LRO_FASTESTMIRROR, /*!< (long 1 or 0)
233         Sort the internal mirrorlist, after it is constructed, by the
234         determined connection speed.
235         Disabled by default. */
236 
237     LRO_FASTESTMIRRORCACHE, /*!< (char *)
238         Path to the fastestmirror's cache file.
239         Used when LRO_FASTESTMIRROR is enabled.
240         If it doesn't exists, it will be created. */
241 
242     LRO_FASTESTMIRRORMAXAGE, /*< (long)
243         Maximum age of a record in cache (seconds).
244         Default: 2592000 (30 days). */
245 
246     LRO_FASTESTMIRRORCB, /* (LrFastestMirrorCb)
247         Fastest mirror status callback */
248 
249     LRO_FASTESTMIRRORDATA, /* (void *)
250         User data for LRO_FASTESTMIRRORCB */
251 
252     LRO_LOWSPEEDTIME, /*< (long)
253         The time in seconds that the transfer should be below the
254         LRO_LOWSPEEDLIMIT for the library to consider it too slow
255         and abort. */
256 
257     LRO_LOWSPEEDLIMIT, /*< (long)
258         The transfer speed in bytes per second that the transfer
259         should be below during LRO_LOWSPEEDTIME seconds for
260         the library to consider it too slow and abort. */
261 
262     /* Repo common options */
263 
264     LRO_GPGCHECK,   /*!< (long 1 or 0)
265         Check GPG signature if available */
266 
267     LRO_CHECKSUM,  /*!< (long 1 or 0)
268         Check files checksum if available */
269 
270     /* LR_YUMREPO specific options */
271 
272     LRO_YUMDLIST,  /*!< (char ** NULL-terminated)
273         Download only specified records from repomd (e.g. ["primary",
274         "filelists", NULL]).
275         Note: Last element of the list must be NULL! */
276 
277     LRO_RPMMDDLIST = LRO_YUMDLIST,
278 
279     LRO_YUMBLIST,  /*!< (char ** NULL-terminated)
280         Do not download this specified records from repomd (skiplist).
281         Note: Last element of the list must be NULL! */
282 
283     LRO_RPMMDBLIST = LRO_YUMBLIST,
284 
285     LRO_HMFCB, /*!< (LrHandleMirrorFailureCb)
286         Handle specific mirror failure callback.
287         Callback called when a repodata download from a mirror fails.
288         This callback gets the user data set by LRO_PROGRESSDATA */
289 
290     LRO_SSLVERIFYPEER, /*!< (long 1 or 0)
291         This option determines whether librepo verifies the authenticity
292         of the peer's certificate.
293         This trust is based on a chain of digital signatures,
294         rooted in certification authority (CA) certificates. */
295 
296     LRO_SSLVERIFYHOST, /*!< (long 1 or 0)
297         This option determines whether librepo verifies that
298         the server cert is for the server it is known as. */
299 
300     LRO_IPRESOLVE, /*!< (LrIpResolveType)
301         Sets what kind of IP addresses to use when resolving host names. */
302 
303     LRO_ALLOWEDMIRRORFAILURES, /*!< (long)
304         If all transfers from a mirror failed (no successful transfer
305         from the mirror exists) and the number
306         of failed downloads is higher or equal to this value
307         the mirror will be skipped (ignored) for all next downloads.
308         Note: Number of failed transfers for a single mirror can
309         outreach this number! For example, if you set this value to 1
310         but you allow 3 parallel downloads it is possible that all
311         three downloads start from the mirror,
312         before any of them can fail. Then, if all three transfers
313         fail, the number of failures for the mirror
314         will be 3, even if this option was set to 1.
315         Set -1 or 0 to disable this option */
316 
317     LRO_ADAPTIVEMIRRORSORTING, /*!< (long 1 or 0)
318         If enabled, internal list of mirrors for each handle is
319         re-sorted after each finished transfer.
320         The the sorting is based on mirror
321         error rate etc. */
322 
323     LRO_GNUPGHOMEDIR, /*!< (char *)
324         Configuration directory for GNUPG (a directory with keyring) */
325 
326     LRO_FASTESTMIRRORTIMEOUT, /*!< (double)
327         Max length of fastest mirror measurement in seconds.
328         Default value is 2sec */
329 
330     LRO_HTTPHEADER, /*!< (char ** NULL-terminated)
331         List of HTTP header to pass to the server and/or proxy in
332         Librepo's HTTP requests. */
333 
334     LRO_OFFLINE, /*!< (long 1 or 0)
335         Make the handle work only locally, all remote URLs are ignored.
336         Remote mirrorlists/metalinks (if they are specified) are ignored.
337         Fastest mirror check (if enabled) is skipped. */
338 
339     LRO_SSLCLIENTCERT, /*!< (char *)
340         Path to the PEM format SSL client certificate librepo should use
341         when talking to the server. */
342 
343     LRO_SSLCLIENTKEY, /*!< (char *)
344         Path to the PEM format SSL client key librepo should use when
345         talking to the server, if not included in the client certificate
346         file. */
347 
348     LRO_SSLCACERT, /*!< (char *)
349         Path to a file containing the list of PEM format trusted CA
350         certificates. */
351 
352     LRO_HTTPAUTHMETHODS, /*!< (LrAuth)
353         Bitmask which tell Librepo which auth methods you wan to use. */
354 
355     LRO_PROXYAUTHMETHODS, /*!< (LrAuth)
356         A long bitmask which tell Librepo which auth methods you want
357         to use for proxy auth. */
358 
359     LRO_FTPUSEEPSV, /*!< (long 1 or 0)
360         Enable/Disable EPSV (Extended Passive mode) for FTP. */
361 
362     LRO_YUMSLIST, /*!< (LrUrlVars *)
363         Repomd records and their substitutions.
364         [{"group_gz", "group"}], ...;
365         If var record is not listed in repomd, librepo will download val
366         instead. After set the list to the handle, it has not to be freed!
367         Handle itself takes care about freeing the list. */
368 
369     LRO_CACHEDIR, /*!< (char *)
370         Path to base cache directory for repositories, used by zchunk to find
371         old files to copy data from.  If this is NULL, zchunk will be disabled */
372 
373     LRO_PRESERVETIME, /*!< (long 1 or 0)
374         If enabled, librepo will try to keep timestamps of the downloaded files
375         in sync with that on the remote side. */
376 
377     LRO_ONETIMEFLAG, /*!< (char *)
378         A one-time flag is a URL query parameter (in the form "key=value") that
379         is added to the first HTTP request for LRO_METALINKURL or
380         LRO_MIRRORLIST (whichever comes first) made with this handle.  Any
381         subsequent requests with this handle, including any retry attempts made
382         by librepo internally, will not get the flag.
383 
384         This is useful for implementing a mechanism for counting the users of a
385         repository (and, by extension, of the OS as a whole) in which all flags
386         received by the server in a specific time period are summed up to
387         produce a good estimate, with the advantage of bundling the flag into
388         regular metadata updates and not sending separate requests just for
389         that purpose alone.
390 
391         The guarantee is that, once set on this handle, the flag will only be
392         used once and then thrown away (set to NULL).  The program may choose
393         to implement a sliding time window used to set this option on a regular
394         basis (such as once per week), to allow for gathering usage statistics
395         over time.
396 
397         For a reference implementation, see the "countme" option in dnf.conf(5)
398         or the associated Fedora change:
399         https://fedoraproject.org/wiki/Changes/DNF_Better_Counting */
400 
401     LRO_SSLVERIFYSTATUS, /*!< (long 1 or 0)
402         This option determines whether librepo verifies the status of the
403         server cert using the 'Certificate Status Request' TLS extension
404         (aka. OCSP stapling).
405         Note that if this option is enabled but the server does not support
406         the TLS extension, the verification will fail. */
407 
408     LRO_PROXY_SSLVERIFYPEER, /*!< (long 1 or 0)
409         This option determines whether librepo verifies the authenticity
410         of the proxy certificate.
411         This trust is based on a chain of digital signatures,
412         rooted in certification authority (CA) certificates. */
413 
414     LRO_PROXY_SSLVERIFYHOST, /*!< (long 1 or 0)
415         This option determines whether librepo verifies
416         the name of the proxy certificate against the host. */
417 
418     LRO_PROXY_SSLCLIENTCERT, /*!< (char *)
419         Path to the PEM format SSL client certificate librepo should use
420         when talking to the proxy. */
421 
422     LRO_PROXY_SSLCLIENTKEY, /*!< (char *)
423         Path to the PEM format SSL client key librepo should use when
424         talking to the proxy, if not included in the client certificate
425         file. */
426 
427     LRO_PROXY_SSLCACERT, /*!< (char *)
428         Path to a file containing the list of PEM format trusted CA
429         certificates. Used for proxy. */
430 
431     LRO_SENTINEL,    /*!< Sentinel */
432 
433 } LrHandleOption; /*!< Handle config options */
434 
435 /** Handle options for the ::lr_handle_getinfo function. */
436 typedef enum {
437     LRI_UPDATE,                 /*!< (long *) */
438     LRI_URLS,                   /*!< (char *** Malloced)
439         NOTE: Returned list must be freed as well as all its items!
440         You could use g_strfreev() function. */
441     LRI_MIRRORLIST,             /*!< (char **) */
442     LRI_MIRRORLISTURL,          /*!< (char **) */
443     LRI_METALINKURL,            /*!< (char **) */
444     LRI_LOCAL,                  /*!< (long *) */
445     LRI_PROGRESSCB,             /*!< (void *) */
446     LRI_PROGRESSDATA,           /*!< (LrProgressCb) */
447     LRI_DESTDIR,                /*!< (char **) */
448     LRI_REPOTYPE,               /*!< (long *) */
449     LRI_USERAGENT,              /*!< (char **) */
450     LRI_YUMDLIST,               /*!< (char *** Malloced)
451         NOTE: Returned list must be freed as well as all its items!
452         You could use g_strfreev() function. */
453     LRI_RPMMDDLIST = LRI_YUMDLIST,
454     LRI_YUMBLIST,               /*!< (char *** Malloced)
455         NOTE: Returned list must be freed as well as all its items!
456         You could use g_strfreev() function. */
457     LRI_RPMMDBLIST = LRI_YUMBLIST,
458     LRI_FETCHMIRRORS,           /*!< (long *) */
459     LRI_MAXMIRRORTRIES,         /*!< (long *) */
460     LRI_VARSUB,                 /*!< (LrUrlVars **) */
461     LRI_MIRRORS,                /*!< (char *** Malloced)
462         Mirrorlist associated with the repository.
463 
464         Mirrors on this list are mirrors parsed from
465         mirrorlist/metalink specified by LRO_MIRRORLIST or
466         from mirrorlist specified by LRO_MIRROSLISTURL and
467         metalink specified by LRO_METALINKURL.
468 
469         No URLs specified by LRO_URLS are included in this list.
470 
471         NOTE: Returned list must be freed as well as all its items!
472         You could use g_strfreev() function. */
473     LRI_METALINK,               /*!< (LrMetalink *) */
474     LRI_FASTESTMIRROR,          /*!< (long *) */
475     LRI_FASTESTMIRRORCACHE,     /*!< (char **) */
476     LRI_FASTESTMIRRORMAXAGE,    /*!< (long *) */
477     LRI_HMFCB,                  /*!< (LrHandleMirrorFailureCb) */
478     LRI_SSLVERIFYPEER,          /*!< (long *) */
479     LRI_SSLVERIFYHOST,          /*!< (long *) */
480     LRI_IPRESOLVE,              /*!< (LrIpResolveType *) */
481     LRI_ALLOWEDMIRRORFAILURES,  /*!< (long *) */
482     LRI_ADAPTIVEMIRRORSORTING,  /*!< (long *) */
483     LRI_GNUPGHOMEDIR,           /*!< (char **) */
484     LRI_FASTESTMIRRORTIMEOUT,   /*!< (double *) */
485     LRI_HTTPHEADER,             /*!< (char *** Malloced)
486         NOTE: Returned list must be freed as well as all its items!
487         You could use g_strfreev() function. */
488     LRI_OFFLINE,                /*!< (long *) */
489     LRI_SSLCLIENTCERT,          /*!< (char **) */
490     LRI_SSLCLIENTKEY,           /*!< (char **) */
491     LRI_SSLCACERT,              /*!< (char **) */
492     LRI_LOWSPEEDTIME,           /*!< (long) */
493     LRI_LOWSPEEDLIMIT,          /*!< (long) */
494     LRI_HTTPAUTHMETHODS,        /*!< (LrAuth) */
495     LRI_PROXYAUTHMETHODS,       /*!< (LrAuth) */
496     LRI_FTPUSEEPSV,             /*!< (long) */
497     LRI_YUMSLIST,               /*!< (LrUrlVars **) */
498     LRI_CACHEDIR,               /*!< (char *) */
499     LRI_SSLVERIFYSTATUS,        /*!< (long *) */
500 
501     LRI_PROXY_SSLVERIFYPEER,    /*!< (long *) */
502     LRI_PROXY_SSLVERIFYHOST,    /*!< (long *) */
503     LRI_PROXY_SSLCLIENTCERT,    /*!< (char **) */
504     LRI_PROXY_SSLCLIENTKEY,     /*!< (char **) */
505     LRI_PROXY_SSLCACERT,        /*!< (char **) */
506 
507     LRI_SENTINEL,
508 } LrHandleInfoOption; /*!< Handle info options */
509 
510 /** Return new handle.
511  * @return              New allocated handle.
512  */
513 LrHandle *
514 lr_handle_init(void);
515 
516 /** Frees handle and its content.
517  * @param handle        Handle.
518  */
519 void
520 lr_handle_free(LrHandle *handle);
521 
522 /** Set option (::LrHandleOption) of the handle.
523  * @param handle        Handle.
524  * @param err           GError **
525  * @param option        Option from ::LrHandleOption enum.
526  * @param ...           Value for the option.
527  * @return              TRUE if everything is ok, FALSE if err is set.
528  */
529 gboolean
530 lr_handle_setopt(LrHandle *handle,
531                  GError **err,
532                  LrHandleOption option,
533                  ...);
534 
535 /** Get information from handle.
536  * Most of returned pointers point directly to the handle internal
537  * values and therefore you should assume that they are only valid until
538  * any manipulation (lr_handle_setopt, lr_handle_perform, ...)
539  * with handle occurs.
540  * NOTE: You should not free or modify the memory returned by this
541  * function unless it is explicitly mentioned!
542  * @param handle        Librepo handle.
543  * @param err           GError **
544  * @param option        Option from ::LrHandleInfoOption enum.
545  * @param ...           Appropriate variable for the selected option.
546  * @return              TRUE if everything is ok, FALSE if err is set.
547  */
548 gboolean
549 lr_handle_getinfo(LrHandle *handle,
550                   GError **err,
551                   LrHandleInfoOption option,
552                   ...);
553 
554 /** Perform repodata download or location.
555  * @param handle        Librepo handle.
556  * @param result        Librepo result.
557  * @param err           GError **
558  * @return              TRUE if everything is ok, FALSE if err is set.
559  */
560 gboolean
561 lr_handle_perform(LrHandle *handle, LrResult *result, GError **err);
562 
563 /** @} */
564 
565 G_END_DECLS
566 
567 #endif
568