1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * All rights reserved.                                                      *
4  *                                                                           *
5  * This file is part of HDF5. The full HDF5 copyright notice, including      *
6  * terms governing use, modification, and redistribution, is contained in    *
7  * the COPYING file, which can be found at the root of the source code       *
8  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
9  * If you do not have access to either file, you may request a copy from     *
10  * help@hdfgroup.org.                                                        *
11  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 
13 /****************/
14 /* Module Setup */
15 /****************/
16 
17 #include "H5PLmodule.h"          /* This source code file is part of the H5PL module */
18 
19 
20 /***********/
21 /* Headers */
22 /***********/
23 #include "H5private.h"      /* Generic Functions            */
24 #include "H5Eprivate.h"     /* Error handling               */
25 #include "H5PLpkg.h"        /* Plugin                       */
26 
27 
28 /****************/
29 /* Local Macros */
30 /****************/
31 
32 
33 /******************/
34 /* Local Typedefs */
35 /******************/
36 
37 
38 /********************/
39 /* Local Prototypes */
40 /********************/
41 
42 
43 /*********************/
44 /* Package Variables */
45 /*********************/
46 
47 
48 /*****************************/
49 /* Library Private Variables */
50 /*****************************/
51 
52 
53 /*******************/
54 /* Local Variables */
55 /*******************/
56 
57 
58 
59 /*-------------------------------------------------------------------------
60  * Function:    H5PLset_loading_state
61  *
62  * Purpose:     Control the loading of dynamic plugin types.
63  *
64  *              The plugin_control_mask parameter is a bitfield that controls
65  *              whether certain classes of plugins (e.g.: filters,
66  *              VOL drivers) will be loaded by the library.
67  *
68  *              plugin bit = 0, will prevent the use of that dynamic plugin type.
69  *              plugin bit = 1, will allow the use of that dynamic plugin type.
70  *
71  *              A list of pre-defined masks can be found in H5PLpublic.h.
72  *              Set the mask to 0 to disable all plugins.
73  *
74  *              This function will not allow plugin types if the pathname
75  *              from the HDF5_PLUGIN_PRELOAD environment variable is set to
76  *              the special "::" string.
77  *
78  * Return:      Success:    Non-negative
79  *              Failture:   Negative
80  *
81  *-------------------------------------------------------------------------
82  */
83 herr_t
H5PLset_loading_state(unsigned int plugin_control_mask)84 H5PLset_loading_state(unsigned int plugin_control_mask)
85 {
86     herr_t  ret_value = SUCCEED;        /* Return value */
87 
88     FUNC_ENTER_API(FAIL)
89     H5TRACE1("e", "Iu", plugin_control_mask);
90 
91     /* Set the plugin control mask */
92     if(H5PL__set_plugin_control_mask(plugin_control_mask) < 0)
93         HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "error setting plugin control mask")
94 
95 done:
96     FUNC_LEAVE_API(ret_value)
97 } /* end H5PLset_loading_state() */
98 
99 
100 /*-------------------------------------------------------------------------
101  * Function:    H5PLget_loading_state
102  *
103  * Purpose:     Get the bitmask that controls whether certain classes
104  *              of plugins (e.g.: filters, VOL drivers) will be loaded
105  *              by the library.
106  *
107  *              Zero if all plugin types are disabled
108  *              Negative if all plugin types are enabled
109  *              Positive if one or more of the plugin types are enabled
110  *
111  * Return:      Success:    Non-negative
112  *              Failture:   Negative
113  *
114  *-------------------------------------------------------------------------
115  */
116 herr_t
H5PLget_loading_state(unsigned int * plugin_control_mask)117 H5PLget_loading_state(unsigned int *plugin_control_mask)
118 {
119     herr_t ret_value = SUCCEED;     /* Return value */
120 
121     FUNC_ENTER_API(FAIL)
122     H5TRACE1("e", "*Iu", plugin_control_mask);
123 
124     if (NULL == plugin_control_mask)
125         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_control_mask parameter cannot be NULL")
126 
127     /* Set the plugin control mask */
128     if(H5PL__get_plugin_control_mask(plugin_control_mask) < 0)
129         HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "error getting plugin control mask")
130 
131 done:
132     FUNC_LEAVE_API(ret_value)
133 } /* end H5PLget_loading_state() */
134 
135 
136 /*-------------------------------------------------------------------------
137  * Function:    H5PLappend
138  *
139  * Purpose:     Insert a plugin search path at the end of the list.
140  *
141  * Return:      Success:    Non-negative
142  *              Failture:   Negative
143  *
144  *-------------------------------------------------------------------------
145  */
146 herr_t
H5PLappend(const char * search_path)147 H5PLappend(const char *search_path)
148 {
149     herr_t ret_value = SUCCEED; /* Return value */
150 
151     FUNC_ENTER_API(FAIL)
152     H5TRACE1("e", "*s", search_path);
153 
154     /* Check args */
155     if (NULL == search_path)
156         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
157     if (0 == HDstrlen(search_path))
158         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
159 
160     /* Append the search path to the path table */
161     if (H5PL__append_path(search_path) < 0)
162         HGOTO_ERROR(H5E_PLUGIN, H5E_CANTAPPEND, FAIL, "unable to append search path")
163 
164 done:
165     FUNC_LEAVE_API(ret_value)
166 } /* end H5PLappend() */
167 
168 
169 /*-------------------------------------------------------------------------
170  * Function:    H5PLprepend
171  *
172  * Purpose:     Insert a plugin search path at the beginning of the list.
173  *
174  * Return:      Success:    Non-negative
175  *              Failture:   Negative
176  *
177  *-------------------------------------------------------------------------
178  */
179 herr_t
H5PLprepend(const char * search_path)180 H5PLprepend(const char *search_path)
181 {
182     herr_t ret_value = SUCCEED; /* Return value */
183 
184     FUNC_ENTER_API(FAIL)
185     H5TRACE1("e", "*s", search_path);
186 
187     /* Check args */
188     if (NULL == search_path)
189         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
190     if (0 == HDstrlen(search_path))
191         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
192 
193     /* Prepend the search path to the path table */
194     if (H5PL__prepend_path(search_path) < 0)
195         HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to prepend search path")
196 
197 done:
198     FUNC_LEAVE_API(ret_value)
199 } /* end H5PLprepend() */
200 
201 
202 /*-------------------------------------------------------------------------
203  * Function:    H5PLreplace
204  *
205  * Purpose:     Replace the path at the specified index. The path at the
206  *              index must exist.
207  *
208  * Return:      Non-negative or success.
209  *
210  *-------------------------------------------------------------------------
211  */
212 herr_t
H5PLreplace(const char * search_path,unsigned int index)213 H5PLreplace(const char *search_path, unsigned int index)
214 {
215     unsigned    num_paths;              /* Current number of stored paths */
216     herr_t      ret_value = SUCCEED;    /* Return value */
217 
218     FUNC_ENTER_API(FAIL)
219     H5TRACE2("e", "*sIu", search_path, index);
220 
221     /* Check args */
222     if (NULL == search_path)
223         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
224     if (0 == HDstrlen(search_path))
225         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
226 
227     /* Check index */
228     num_paths = H5PL__get_num_paths();
229     if (0 == num_paths)
230         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "path table is empty")
231     else if (index >= num_paths)
232         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
233 
234     /* Insert the search path into the path table */
235     if (H5PL__replace_path(search_path, index) < 0)
236         HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to replace search path")
237 
238 done:
239     FUNC_LEAVE_API(ret_value)
240 } /* end H5PLreplace() */
241 
242 
243 /*-------------------------------------------------------------------------
244  * Function:    H5PLinsert
245  *
246  * Purpose:     Insert a plugin search path at the specified index, moving
247  *              other paths after the index.
248  *
249  * Return:      Success:    Non-negative
250  *              Failture:   Negative
251  *
252  *-------------------------------------------------------------------------
253  */
254 herr_t
H5PLinsert(const char * search_path,unsigned int index)255 H5PLinsert(const char *search_path, unsigned int index)
256 {
257     unsigned    num_paths;              /* Current number of stored paths */
258     herr_t      ret_value = SUCCEED;    /* Return value */
259 
260     FUNC_ENTER_API(FAIL)
261     H5TRACE2("e", "*sIu", search_path, index);
262 
263     /* Check args */
264     if (NULL == search_path)
265         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
266     if (0 == HDstrlen(search_path))
267         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
268 
269     /* Check index */
270     num_paths = H5PL__get_num_paths();
271     if ((0 != num_paths) && (index >= num_paths))
272         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
273 
274     /* Insert the search path into the path table */
275     if (H5PL__insert_path(search_path, index) < 0)
276         HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to insert search path")
277 
278 done:
279     FUNC_LEAVE_API(ret_value)
280 } /* end H5PLinsert() */
281 
282 
283 /*-------------------------------------------------------------------------
284  * Function:    H5PLremove
285  *
286  * Purpose:     Remove the plugin path at the specifed index and compact
287  *              the list.
288  *
289  * Return:      Success:    Non-negative
290  *              Failture:   Negative
291  *
292  * Return:      Non-negative or success.
293  *
294  *-------------------------------------------------------------------------
295  */
296 herr_t
H5PLremove(unsigned int index)297 H5PLremove(unsigned int index)
298 {
299     unsigned    num_paths;              /* Current number of stored paths */
300     herr_t      ret_value = SUCCEED;    /* Return value */
301 
302     FUNC_ENTER_API(FAIL)
303     H5TRACE1("e", "Iu", index);
304 
305     /* Check index */
306     num_paths = H5PL__get_num_paths();
307     if (0 == num_paths)
308         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "path table is empty")
309     else if (index >= num_paths)
310         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
311 
312     /* Delete the search path from the path table */
313     if (H5PL__remove_path(index) < 0)
314         HGOTO_ERROR(H5E_PLUGIN, H5E_CANTDELETE, FAIL, "unable to remove search path")
315 
316 done:
317     FUNC_LEAVE_API(ret_value)
318 } /* end H5PLremove() */
319 
320 
321 /*-------------------------------------------------------------------------
322  * Function:    H5PLget
323  *
324  * Purpose:     Query the plugin path at a specified index.
325  *
326  *  If 'path_buf' is non-NULL then up to 'buf_size' bytes will be written into
327  *  that buffer and the length of the path name will be returned.
328  *
329  *  If 'path_buf' is NULL, this function will simply return the number of
330  *  characters required to store the path name, ignoring 'path_buf' and
331  *  'buf_size'
332  *
333  *  If an error occurs then the buffer pointed to by 'path_buf'
334  *  (NULL or non-NULL) will be unchanged and the function will return a
335  *  negative value.
336  *
337  *  If a zero is returned for the name's length, then there is no path name
338  *  associated with the index and the 'path_buf' buffer will be unchanged.
339  *
340  * Return:  Success:    The length of path
341  *          Failure:    A negative value
342  *
343  *-------------------------------------------------------------------------
344  */
345 ssize_t
H5PLget(unsigned int index,char * path_buf,size_t buf_size)346 H5PLget(unsigned int index, char *path_buf, size_t buf_size)
347 {
348     unsigned    num_paths;              /* Current number of stored paths */
349     const char *path = NULL;            /* path from table */
350     size_t      path_len = 0;           /* Length of path */
351     ssize_t     ret_value = 0;          /* Return value */
352 
353     FUNC_ENTER_API(FAIL)
354     H5TRACE3("Zs", "Iu*sz", index, path_buf, buf_size);
355 
356     /* Check index */
357     num_paths = H5PL__get_num_paths();
358     if (0 == num_paths)
359         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "path table is empty")
360     else if (index >= num_paths)
361         HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
362 
363     /* Check if the search table is empty */
364     if (H5PL__get_num_paths() == 0)
365         HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, (-1), "plugin search path table is empty")
366 
367     /* Get the path at the specified index and its length */
368     if (NULL == (path = H5PL__get_path(index)))
369         HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, (-1), "no path stored at that index")
370     path_len = HDstrlen(path);
371 
372     /* If the path buffer is not NULL, copy the path to the buffer */
373     if (path_buf) {
374         HDstrncpy(path_buf, path, MIN((size_t)(path_len + 1), buf_size));
375         if ((size_t)path_len >= buf_size)
376             path_buf[buf_size - 1] = '\0';
377     } /* end if */
378 
379     /* Set return value */
380     ret_value = (ssize_t)path_len;
381 
382 done:
383     FUNC_LEAVE_API(ret_value)
384 } /* end H5PLget() */
385 
386 
387 /*-------------------------------------------------------------------------
388  * Function:    H5PLsize
389  *
390  * Purpose:     Get the number of stored plugin paths.
391  *              XXX: This is a terrible name. Can it be changed?
392  *
393  * Return:      SUCCEED/FAIL
394  *
395  *-------------------------------------------------------------------------
396  */
397 herr_t
H5PLsize(unsigned int * num_paths)398 H5PLsize(unsigned int *num_paths)
399 {
400     herr_t ret_value = SUCCEED; /* Return value */
401 
402     FUNC_ENTER_API(FAIL)
403     H5TRACE1("e", "*Iu", num_paths);
404 
405     /* Check arguments */
406     if (!num_paths)
407         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "num_paths parameter cannot be NULL")
408 
409     /* Get the number of stored plugin paths */
410     *num_paths = H5PL__get_num_paths();
411 
412 done:
413     FUNC_LEAVE_API(ret_value)
414 } /* end H5PLsize() */
415 
416