1*bf6873c5SCy Schubert /* 2*bf6873c5SCy Schubert * Prototypes for vector handling. 3*bf6873c5SCy Schubert * 4*bf6873c5SCy Schubert * A vector is a list of strings, with dynamic resizing of the list as new 5*bf6873c5SCy Schubert * strings are added and support for various operations on strings (such as 6*bf6873c5SCy Schubert * splitting them on delimiters). 7*bf6873c5SCy Schubert * 8*bf6873c5SCy Schubert * Vectors require list of strings, not arbitrary binary data, and cannot 9*bf6873c5SCy Schubert * handle data elements containing nul characters. 10*bf6873c5SCy Schubert * 11*bf6873c5SCy Schubert * This is based on the util/vector.c library, but that library uses xmalloc 12*bf6873c5SCy Schubert * routines to exit the program if memory allocation fails. This is a 13*bf6873c5SCy Schubert * modified version of the vector library that instead returns false on 14*bf6873c5SCy Schubert * failure to allocate memory, allowing the caller to do appropriate recovery. 15*bf6873c5SCy Schubert * 16*bf6873c5SCy Schubert * Only the portions of the vector library used by PAM modules are 17*bf6873c5SCy Schubert * implemented. 18*bf6873c5SCy Schubert * 19*bf6873c5SCy Schubert * The canonical version of this file is maintained in the rra-c-util package, 20*bf6873c5SCy Schubert * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. 21*bf6873c5SCy Schubert * 22*bf6873c5SCy Schubert * Written by Russ Allbery <eagle@eyrie.org> 23*bf6873c5SCy Schubert * Copyright 2010-2011, 2014 24*bf6873c5SCy Schubert * The Board of Trustees of the Leland Stanford Junior University 25*bf6873c5SCy Schubert * 26*bf6873c5SCy Schubert * Copying and distribution of this file, with or without modification, are 27*bf6873c5SCy Schubert * permitted in any medium without royalty provided the copyright notice and 28*bf6873c5SCy Schubert * this notice are preserved. This file is offered as-is, without any 29*bf6873c5SCy Schubert * warranty. 30*bf6873c5SCy Schubert * 31*bf6873c5SCy Schubert * SPDX-License-Identifier: FSFAP 32*bf6873c5SCy Schubert */ 33*bf6873c5SCy Schubert 34*bf6873c5SCy Schubert #ifndef PAM_UTIL_VECTOR_H 35*bf6873c5SCy Schubert #define PAM_UTIL_VECTOR_H 1 36*bf6873c5SCy Schubert 37*bf6873c5SCy Schubert #include <config.h> 38*bf6873c5SCy Schubert #include <portable/macros.h> 39*bf6873c5SCy Schubert #include <portable/stdbool.h> 40*bf6873c5SCy Schubert 41*bf6873c5SCy Schubert #include <stddef.h> 42*bf6873c5SCy Schubert 43*bf6873c5SCy Schubert struct vector { 44*bf6873c5SCy Schubert size_t count; 45*bf6873c5SCy Schubert size_t allocated; 46*bf6873c5SCy Schubert char **strings; 47*bf6873c5SCy Schubert }; 48*bf6873c5SCy Schubert 49*bf6873c5SCy Schubert BEGIN_DECLS 50*bf6873c5SCy Schubert 51*bf6873c5SCy Schubert /* Default to a hidden visibility for all util functions. */ 52*bf6873c5SCy Schubert #pragma GCC visibility push(hidden) 53*bf6873c5SCy Schubert 54*bf6873c5SCy Schubert /* Create a new, empty vector. Returns NULL on memory allocation failure. */ 55*bf6873c5SCy Schubert struct vector *vector_new(void) __attribute__((__malloc__)); 56*bf6873c5SCy Schubert 57*bf6873c5SCy Schubert /* 58*bf6873c5SCy Schubert * Create a new vector that's a copy of an existing vector. Returns NULL on 59*bf6873c5SCy Schubert * memory allocation failure. 60*bf6873c5SCy Schubert */ 61*bf6873c5SCy Schubert struct vector *vector_copy(const struct vector *) 62*bf6873c5SCy Schubert __attribute__((__malloc__, __nonnull__)); 63*bf6873c5SCy Schubert 64*bf6873c5SCy Schubert /* 65*bf6873c5SCy Schubert * Add a string to a vector. Resizes the vector if necessary. Returns false 66*bf6873c5SCy Schubert * on failure to allocate memory. 67*bf6873c5SCy Schubert */ 68*bf6873c5SCy Schubert bool vector_add(struct vector *, const char *string) 69*bf6873c5SCy Schubert __attribute__((__nonnull__)); 70*bf6873c5SCy Schubert 71*bf6873c5SCy Schubert /* 72*bf6873c5SCy Schubert * Resize the array of strings to hold size entries. Saves reallocation work 73*bf6873c5SCy Schubert * in vector_add if it's known in advance how many entries there will be. 74*bf6873c5SCy Schubert * Returns false on failure to allocate memory. 75*bf6873c5SCy Schubert */ 76*bf6873c5SCy Schubert bool vector_resize(struct vector *, size_t size) __attribute__((__nonnull__)); 77*bf6873c5SCy Schubert 78*bf6873c5SCy Schubert /* 79*bf6873c5SCy Schubert * Reset the number of elements to zero, freeing all of the strings for a 80*bf6873c5SCy Schubert * regular vector, but not freeing the strings array (to cut down on memory 81*bf6873c5SCy Schubert * allocations if the vector will be reused). 82*bf6873c5SCy Schubert */ 83*bf6873c5SCy Schubert void vector_clear(struct vector *) __attribute__((__nonnull__)); 84*bf6873c5SCy Schubert 85*bf6873c5SCy Schubert /* Free the vector and all resources allocated for it. */ 86*bf6873c5SCy Schubert void vector_free(struct vector *); 87*bf6873c5SCy Schubert 88*bf6873c5SCy Schubert /* 89*bf6873c5SCy Schubert * Split functions build a vector from a string. vector_split_multi splits on 90*bf6873c5SCy Schubert * a set of characters. If the vector argument is NULL, a new vector is 91*bf6873c5SCy Schubert * allocated; otherwise, the provided one is reused. Returns NULL on memory 92*bf6873c5SCy Schubert * allocation failure, after which the provided vector may have been modified 93*bf6873c5SCy Schubert * to only have partial results. 94*bf6873c5SCy Schubert * 95*bf6873c5SCy Schubert * Empty strings will yield zero-length vectors. Adjacent delimiters are 96*bf6873c5SCy Schubert * treated as a single delimiter by vector_split_multi. Any leading or 97*bf6873c5SCy Schubert * trailing delimiters are ignored, so this function will never create 98*bf6873c5SCy Schubert * zero-length strings (similar to the behavior of strtok). 99*bf6873c5SCy Schubert */ 100*bf6873c5SCy Schubert struct vector *vector_split_multi(const char *string, const char *seps, 101*bf6873c5SCy Schubert struct vector *) 102*bf6873c5SCy Schubert __attribute__((__nonnull__(1, 2))); 103*bf6873c5SCy Schubert 104*bf6873c5SCy Schubert /* 105*bf6873c5SCy Schubert * Exec the given program with the vector as its arguments. Return behavior 106*bf6873c5SCy Schubert * is the same as execv. Note the argument order is different than the other 107*bf6873c5SCy Schubert * vector functions (but the same as execv). The vector_exec_env variant 108*bf6873c5SCy Schubert * calls execve and passes in the environment for the program. 109*bf6873c5SCy Schubert */ 110*bf6873c5SCy Schubert int vector_exec(const char *path, struct vector *) 111*bf6873c5SCy Schubert __attribute__((__nonnull__)); 112*bf6873c5SCy Schubert int vector_exec_env(const char *path, struct vector *, const char *const env[]) 113*bf6873c5SCy Schubert __attribute__((__nonnull__)); 114*bf6873c5SCy Schubert 115*bf6873c5SCy Schubert /* Undo default visibility change. */ 116*bf6873c5SCy Schubert #pragma GCC visibility pop 117*bf6873c5SCy Schubert 118*bf6873c5SCy Schubert END_DECLS 119*bf6873c5SCy Schubert 120*bf6873c5SCy Schubert #endif /* UTIL_VECTOR_H */ 121