1/* prop.h -- property request/response management routines
2 *
3 * Author: Chris Newman
4 * Removal of implementation-specific details by: Rob Siemborski
5 *
6 * This is intended to be used to create a list of properties to request,
7 * and _then_ request values for all properties.  Any change to the request
8 * list will discard any existing values.  This assumption allows a very
9 * efficient and simple memory model.  This was designed for SASL API auxiliary
10 * property support, but would be fine for other contexts where this property
11 * model is appropriate.
12 *
13 * The "struct propctx" is allocated by prop_new and is a fixed size structure.
14 * If a prop_init() call were added, it would be reasonable to embed a "struct
15 * propctx" in another structure.  prop_new also allocates a pool of memory
16 * (in the vbase field) which will be used for an array of "struct propval"
17 * to list all the requested properties.
18 *
19 * Properties may be multi-valued.
20 */
21
22#ifndef PROP_H
23#define PROP_H 1
24
25/* The following ifdef block is the standard way of creating macros
26 * which make exporting from a DLL simpler. All files within this DLL
27 * are compiled with the LIBSASL_EXPORTS symbol defined on the command
28 * line. this symbol should not be defined on any project that uses
29 * this DLL. This way any other project whose source files include
30 * this file see LIBSASL_API functions as being imported from a DLL,
31 * wheras this DLL sees symbols defined with this macro as being
32 * exported.  */
33/* Under Unix, life is simpler: we just need to mark library functions
34 * as extern.  (Technically, we don't even have to do that.) */
35#ifdef WIN32
36# ifdef LIBSASL_EXPORTS
37#  define LIBSASL_API  __declspec(dllexport)
38# else /* LIBSASL_EXPORTS */
39#  define LIBSASL_API  __declspec(dllimport)
40# endif /* LIBSASL_EXPORTS */
41#else /* WIN32 */
42# define LIBSASL_API extern
43#endif /* WIN32 */
44
45/* Same as above, but used during a variable declaration. Only Unix definition
46 * is different, as we can't assign an initial value to an extern variable */
47#ifdef WIN32
48# ifdef LIBSASL_EXPORTS
49#  define LIBSASL_VAR  __declspec(dllexport)
50# else /* LIBSASL_EXPORTS */
51#  define LIBSASL_VAR  __declspec(dllimport)
52# endif /* LIBSASL_EXPORTS */
53#else /* WIN32 */
54# define LIBSASL_VAR
55#endif /* WIN32 */
56
57/* the resulting structure for property values
58 */
59struct propval {
60    const char *name;	 /* name of property; NULL = end of list */
61                         /* same pointer used in request will be used here */
62    const char **values; /* list of strings, values == NULL if property not
63			  * found, *values == NULL if property found with
64			  * no values */
65    unsigned nvalues;    /* total number of value strings */
66    unsigned valsize;	 /* total size in characters of all value strings */
67};
68
69/*
70 * private internal structure
71 */
72#define PROP_DEFAULT 4		/* default number of propvals to assume */
73struct propctx;
74
75#ifdef __cplusplus
76extern "C" {
77#endif
78
79/* create a property context
80 *  estimate -- an estimate of the storage needed for requests & responses
81 *              0 will use module default
82 * returns a new property context on success and NULL on any error
83 */
84LIBSASL_API struct propctx *prop_new(unsigned estimate);
85
86/* create new propctx which duplicates the contents of an existing propctx
87 * returns SASL_OK on success
88 * possible other return values include: SASL_NOMEM, SASL_BADPARAM
89 */
90LIBSASL_API int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx);
91
92/* Add property names to request
93 *  ctx       -- context from prop_new()
94 *  names     -- list of property names; must persist until context freed
95 *               or requests cleared (This extends to other contexts that
96 *               are dup'ed from this one, and their children, etc)
97 *
98 * NOTE: may clear values from context as side-effect
99 * returns SASL_OK on success
100 * possible other return values include: SASL_NOMEM, SASL_BADPARAM
101 */
102LIBSASL_API int prop_request(struct propctx *ctx, const char **names);
103
104/* return array of struct propval from the context
105 *  return value persists until next call to
106 *   prop_request, prop_clear or prop_dispose on context
107 *
108 *  returns NULL on error
109 */
110LIBSASL_API const struct propval *prop_get(struct propctx *ctx);
111
112/* Fill in an array of struct propval based on a list of property names
113 *  return value persists until next call to
114 *   prop_request, prop_clear or prop_dispose on context
115 *  returns number of matching properties which were found (values != NULL)
116 *  if a name requested here was never requested by a prop_request, then
117 *  the name field of the associated vals entry will be set to NULL
118 *
119 * The vals array MUST be atleast as long as the names array.
120 *
121 * returns # of matching properties on success
122 * possible other return values include: SASL_BADPARAM
123 */
124LIBSASL_API int prop_getnames(struct propctx *ctx, const char **names,
125		  struct propval *vals);
126
127/* clear values and optionally requests from property context
128 *  ctx      -- property context
129 *  requests -- 0 = don't clear requests, 1 = clear requests
130 */
131LIBSASL_API void prop_clear(struct propctx *ctx, int requests);
132
133/* erase the value of a property
134 */
135LIBSASL_API void prop_erase(struct propctx *ctx, const char *name);
136
137/* dispose of property context
138 *  ctx      -- is disposed and set to NULL; noop if ctx or *ctx is NULL
139 */
140LIBSASL_API void prop_dispose(struct propctx **ctx);
141
142
143/****fetcher interfaces****/
144
145/* format the requested property names into a string
146 *  ctx    -- context from prop_new()/prop_request()
147 *  sep    -- separator between property names (unused if none requested)
148 *  seplen -- length of separator, if < 0 then strlen(sep) will be used
149 *  outbuf -- output buffer
150 *  outmax -- maximum length of output buffer including NUL terminator
151 *  outlen -- set to length of output string excluding NUL terminator
152 * returns SASL_OK on success
153 * returns SASL_BADPARAM or amount of additional space needed on failure
154 */
155LIBSASL_API int prop_format(struct propctx *ctx, const char *sep, int seplen,
156		char *outbuf, unsigned outmax, unsigned *outlen);
157
158/* add a property value to the context
159 *  ctx    -- context from prop_new()/prop_request()
160 *  name   -- name of property to which value will be added
161 *            if NULL, add to the same name as previous prop_set/setvals call
162 *  value  -- a value for the property; will be copied into context
163 *            if NULL, remove existing values
164 *  vallen -- length of value, if <= 0 then strlen(value) will be used
165 * returns SASL_OK on success
166 * possible error return values include: SASL_BADPARAM, SASL_NOMEM
167 */
168LIBSASL_API int prop_set(struct propctx *ctx, const char *name,
169	     const char *value, int vallen);
170
171/* set the values for a property
172 *  ctx    -- context from prop_new()/prop_request()
173 *  name   -- name of property to which value will be added
174 *            if NULL, add to the same name as previous prop_set/setvals call
175 *  values -- array of values, ending in NULL.  Each value is a NUL terminated
176 *            string
177 * returns SASL_OK on success
178 * possible error return values include: SASL_BADPARAM, SASL_NOMEM
179 */
180LIBSASL_API int prop_setvals(struct propctx *ctx, const char *name,
181		 const char **values);
182
183#ifdef __cplusplus
184}
185#endif
186
187#endif /* PROP_H */
188