1/* SASL Config file API
2 * Rob Siemborski
3 * Tim Martin (originally in Cyrus distribution)
4 * $Id: config.c,v 1.3 2004/07/07 22:48:35 snsimon Exp $
5 */
6/*
7 * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in
18 *    the documentation and/or other materials provided with the
19 *    distribution.
20 *
21 * 3. The name "Carnegie Mellon University" must not be used to
22 *    endorse or promote products derived from this software without
23 *    prior written permission. For permission or any other legal
24 *    details, please contact
25 *      Office of Technology Transfer
26 *      Carnegie Mellon University
27 *      5000 Forbes Avenue
28 *      Pittsburgh, PA  15213-3890
29 *      (412) 268-4387, fax: (412) 268-7395
30 *      tech-transfer@andrew.cmu.edu
31 *
32 * 4. Redistributions of any form whatsoever must retain the following
33 *    acknowledgment:
34 *    "This product includes software developed by Computing Services
35 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36 *
37 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46/*
47 * Current Valid keys:
48 *
49 * canon_user_plugin: <string>
50 * pwcheck_method: <string>
51 * auto_transition: <boolean>
52 * plugin_list: <string>
53 *
54 * srvtab: <string>
55 */
56
57
58#include "sasl.h"
59#include "saslint.h"
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <ctype.h>
64
65struct configlist {
66    char *key;
67    char *value;
68};
69
70static struct configlist *configlist;
71static int nconfiglist;
72
73#define CONFIGLISTGROWSIZE 100
74
75int sasl_config_init(const char *filename)
76{
77    FILE *infile;
78    int lineno = 0;
79    int alloced = 0;
80    char buf[4096];
81    char *p, *key;
82    int result;
83
84    nconfiglist=0;
85
86    infile = fopen(filename, "r");
87    if (!infile) {
88      return SASL_CONTINUE;
89    }
90
91    while (fgets(buf, sizeof(buf), infile)) {
92	lineno++;
93
94	if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
95	for (p = buf; *p && isspace((int) *p); p++);
96	if (!*p || *p == '#') continue;
97
98	key = p;
99	while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) {
100	    if (isupper((int) *p)) *p = tolower(*p);
101	    p++;
102	}
103	if (*p != ':') {
104	  return SASL_FAIL;
105	}
106	*p++ = '\0';
107
108	while (*p && isspace((int) *p)) p++;
109
110	if (!*p) {
111	  return SASL_FAIL;
112	}
113
114	if (nconfiglist == alloced) {
115	    alloced += CONFIGLISTGROWSIZE;
116	    configlist=sasl_REALLOC((char *)configlist,
117				    alloced * sizeof(struct configlist));
118	    if (configlist==NULL) return SASL_NOMEM;
119	}
120
121
122
123	result = _sasl_strdup(key,
124			      &(configlist[nconfiglist].key),
125			      NULL);
126	if (result!=SASL_OK) return result;
127	result = _sasl_strdup(p,
128			      &(configlist[nconfiglist].value),
129			      NULL);
130	if (result!=SASL_OK) return result;
131
132	nconfiglist++;
133    }
134    fclose(infile);
135
136    return SASL_OK;
137}
138
139const char *sasl_config_getstring(const char *key,const char *def)
140{
141    int opt;
142
143    for (opt = 0; opt < nconfiglist; opt++) {
144	if (*key == configlist[opt].key[0] &&
145	    !strcmp(key, configlist[opt].key))
146	  return configlist[opt].value;
147    }
148    return def;
149}
150