/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* auxprop.c - auxilliary property support
* Rob Siemborski
* $Id: auxprop.c,v 1.10 2003/03/19 18:25:27 rjs3 Exp $
*/
/*
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any other legal
* details, please contact
* Office of Technology Transfer
* Carnegie Mellon University
* 5000 Forbes Avenue
* Pittsburgh, PA 15213-3890
* (412) 268-4387, fax: (412) 268-7395
* tech-transfer@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <sasl.h>
#include <prop.h>
#include <ctype.h>
#include "saslint.h"
struct proppool
{
* of char** area and beginning of char* area */
};
struct propctx {
};
typedef struct auxprop_plug_list
{
#ifdef _SUN_SDK_
char *plugname;
#endif /* _SUN_SDK_ */
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
{
/* minus 1 for the one that is already a part of the array
* in the struct */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_*/
return ret;
}
/* Resize a proppool. Invalidates the unused value for this pool */
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_*/
return ret;
}
{
ctx->used_values = 0;
return SASL_OK;
}
/* create a property context
* estimate -- an estimate of the storage needed for requests & responses
* 0 will use module default
* returns NULL on error
*/
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_*/
}
return new_ctx;
}
/* create new propctx which duplicates the contents of an existing propctx
* returns -1 on error
*/
{
unsigned i;
int result;
/* What is the total allocated size of src_ctx? */
while(pool) {
}
/* allocate the new context */
if(!retval) return SASL_NOMEM;
/* data_end should still be OK */
/* Now dup the values */
for(i=0; i<src_ctx->used_values; i++) {
goto fail;
}
return SASL_OK;
fail:
return result;
}
/*
* dispose of property context
* ctx -- is disposed and set to NULL; noop if ctx or *ctx is NULL
*/
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_*/
}
#ifdef _SUN_SDK_
sasl_sun_FREE(*ctx);
#else
#endif /* _SUN_SDK_*/
return;
}
/* Add property names to request
* ctx -- context from prop_new()
* names -- list of property names; must persist until context freed
* or requests cleared
*
* NOTE: may clear values from context as side-effect
* returns -1 on error
*/
{
/* Count how many we need to add */
/* Do we need to add ANY? */
if(!new_values) return SASL_OK;
/* We always want atleast on extra to mark the end of the array */
/* Do we need to increase the size of our propval table? */
unsigned max_in_pool;
/* Do we need a larger base pool? */
if(total_values <= max_in_pool) {
/* Don't increase the size of the base pool, just use what
we need */
* ctx->allocated_values);
} else {
/* We need to allocate more! */
unsigned new_alloc_length;
while(total_values > new_alloc_length) {
new_alloc_length *= 2;
}
return SASL_NOMEM;
}
/* It worked! Update the structure! */
}
/* Clear out new propvals */
/* Finish updating the context -- we've extended the list! */
/* ctx->list_end = (char **)(ctx->values + ctx->allocated_values); */
/* xxx test here */
}
/* Now do the copy, or referencing rather */
for(i=0;i<new_values;i++) {
unsigned j, flag;
flag = 0;
/* Check for dups */
for(j=0;j<ctx->used_values;j++) {
flag = 1;
break;
}
}
/* We already have it... skip! */
if(flag) continue;
}
prop_clear(ctx, 0);
return SASL_OK;
}
/* return array of struct propval from the context
* return value persists until next call to
* prop_request, prop_clear or prop_dispose on context
*/
{
}
/* Fill in an array of struct propval based on a list of property names
* return value persists until next call to
* prop_request, prop_clear or prop_dispose on context
* returns -1 on error (no properties ever requested, ctx NULL, etc)
* returns number of matching properties which were found (values != NULL)
* if a name requested here was never requested by a prop_request, then
* the name field of the associated vals entry will be set to NULL
*/
{
int found_names = 0;
const char **curname;
found_names++;
goto next;
}
}
/* If we are here, we didn't find it */
next:
cur++;
}
return found_names;
}
/* clear values and optionally requests from property context
* ctx -- property context
* requests -- 0 = don't clear requests, 1 = clear requests
*/
{
unsigned i;
#ifdef _SUN_SDK_
if(!ctx) return;
#endif /* _SUN_SDK_ */
/* We're going to need a new proppool once we reset things */
if(requests) {
/* We're wiping the whole shebang */
ctx->used_values = 0;
} else {
/* Need to keep around old requets */
for(i=0; i<ctx->used_values; i++) {
}
}
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
}
/* Update allocation-related metadata */
/* Setup pointers for the values array */
/* Setup the pools */
/* Reset list_end and data_end for the new memory pool */
return;
}
/*
* erase the value of a property
*/
{
int i;
/*
* Yes, this is casting away the const, but
* we should be okay because the only place this
* memory should be is in the proppool's
*/
}
break;
}
}
return;
}
/****fetcher interfaces****/
/* format the requested property names into a string
* ctx -- context from prop_new()/prop_request()
* sep -- separator between property names (unused if none requested)
* seplen -- length of separator, if < 0 then strlen(sep) will be used
* outbuf -- output buffer
* outmax -- maximum length of output buffer including NUL terminator
* outlen -- set to length of output string excluding NUL terminator
* returns 0 on success and amount of additional space needed on failure
*/
{
}
*outbuf = '\0';
} else {
flag = 1;
}
}
return SASL_OK;
}
/* add a property value to the context
* ctx -- context from prop_new()/prop_request()
* name -- name of property to which value will be added
* value -- a value for the property; will be copied into context
* if NULL, remove existing values
* vallen -- length of value, if <= 0 then strlen(value) will be used
*/
{
if(!ctx) return SASL_BADPARAM;
if(name) {
break;
}
}
/* Couldn't find it! */
}
if(name) /* New Entry */ {
if(!value) {
/* If we would be adding a null value, then we are done */
return SASL_OK;
}
while(*tmp) {
nvalues++;
tmp++;
}
}
if(value) {
nvalues++; /* for the new value */
}
/* Allocate a new proppool */
}
/* Grab the memory */
/* Finish updating the context */
/* If we don't have an actual value to fill in, we are done */
if(!value)
return SASL_OK;
if(old_values) {
tmp = (char **)old_values;
while(*tmp) {
}
}
/* Now allocate the last entry */
if(vallen <= 0)
else
needed *= 2;
}
/* Allocate a new proppool */
}
/* Update the data_end pointer */
/* Copy and setup the new value! */
} else /* Appending an entry */ {
char **tmp;
/* If we are setting it to be NULL, we are done */
size = sizeof(char*);
/* Is it in the current pool, and will it fit in the unused space? */
/* recursively call the not-fast way */
}
/* Note the invariant: the previous value list must be
at the top of the CURRENT pool at this point */
/* Grab the memory */
/* Now allocate the last entry */
if(vallen <= 0)
else
needed *= 2;
}
/* Allocate a new proppool */
}
/* Update the data_end pointer */
/* Copy and setup the new value! */
}
return SASL_OK;
}
/* set the values for a property
* ctx -- context from prop_new()/prop_request()
* name -- name of property to which value will be added
* values -- array of values, ending in NULL. Each value is a NUL terminated
* string
*/
const char **values)
{
if(!ctx) return SASL_BADPARAM;
/* If they want us to add no values, we can do that */
/* Basically, use prop_set to do all our dirty work for us */
if(name) {
val++;
}
}
return result;
}
/* Request a set of auxiliary properties
* conn connection context
* propnames list of auxiliary property names to request ending with
* NULL.
*
* Subsequent calls will add items to the request list. Call with NULL
* to clear the request list.
*
* errors
* SASL_OK -- success
* SASL_NOMEM -- out of memory
*/
{
int result;
if(!conn) return SASL_BADPARAM;
if(!propnames) {
return SASL_OK;
}
}
/* Returns current auxiliary property context.
* Use functions in prop.h to access content
*
*
*
* returns NULL if conn is invalid.
*/
{
}
/* add an auxiliary property plugin */
#ifdef _SUN_SDK_
{
}
const char *plugname,
#else
int sasl_auxprop_add_plugin(const char *plugname,
#endif /* _SUN_SDK_ */
{
#ifdef _SUN_SDK_
/* Check to see if this plugin has already been registered */
return SASL_OK;
}
}
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
return result;
}
/* We require that this function is implemented */
#ifdef _SUN_SDK_
/* Check plugin to make sure name is non-NULL */
return SASL_BADPROT;
}
#endif /* _SUN_SDK_ */
if(!new_item) return SASL_NOMEM;
#ifdef _SUN_SDK_
return SASL_NOMEM;
}
#endif /* _SUN_SDK_ */
/* These will load from least-important to most important */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
return SASL_OK;
}
#ifdef _SUN_SDK_
#else
void _sasl_auxprop_free()
#endif /* _SUN_SDK_ */
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
}
#ifdef _SUN_SDK_
#else
auxprop_head = NULL;
#endif /* _SUN_SDK_ */
}
/* Do the callbacks for auxprop lookups */
unsigned flags,
{
void *context;
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
}
if(!plist) {
/* Do lookup in all plugins */
found=1;
}
} else {
/* Do lookup in all *specified* plugins, in order */
while(*thisplugin) {
char *p;
int last=0;
if(!(*thisplugin)) break;
else *p='\0';
/* Skip non-matching plugins */
continue;
found=1;
}
if(last) break;
thisplugin = p+1;
}
}
if(!found)
"could not find auxprop plugin, was searching for '%s'",
}