]> andersk Git - moira.git/blob - update/config.c
Read it and weep.
[moira.git] / update / config.c
1 /* $Header$
2  *
3  * Routines to handle configuration file for Moira's update_server.
4  * These routines must load the file into memory rather than parse
5  * it each time as one of the things the server may do is chroot()
6  * itself.
7  *
8  * (c) Copyright 1992 by the Massachusetts Institute of Technology.
9  * For copying and distribution information, please see the file
10  * <mit-copyright.h>.
11  */
12
13 #include <mit-copyright.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/file.h>
20 #include <fcntl.h>
21 #include <moira.h>
22
23
24 #define CONFIG_FILE     "/etc/athena/moira.conf"
25
26 /* Variables currently supported:
27  * chroot directory     daemon will run chrooted to this directory
28  * user username        daemon will run with this user's uid
29  * port portname        daemon will listen on this port number
30  * nofork               server stays in foreground & logs to stdout
31  * auth krbname         this user is authorized to connect
32  * noclobber            will not overwrite existing files
33  * noexec               will not execute instructions received
34  */
35
36 static char *config_buf = NULL;
37 static char **config_keys, **config_values;
38
39
40 static init()
41 {
42     int fd, count = 0;
43     struct stat st;
44     char *p, *start;
45
46     /* Only execute once */
47     if (config_buf) return(MR_SUCCESS);
48
49     fd = open(CONFIG_FILE, O_RDONLY, 0);
50     if (fd < 0) {
51         config_buf = "";
52         config_keys = (char **)malloc(sizeof(char *) * 2);
53         config_keys[0] = config_keys[1] = NULL;
54         return(MR_SUCCESS);
55     }
56     if (fstat(fd, &st) < 0) {
57         return(MR_INTERNAL);
58     }
59     config_buf = (char *) malloc(st.st_size + 2);
60     if (config_buf == NULL) {
61         return(MR_NO_MEM);
62     }
63     if (read(fd, config_buf, st.st_size) < st.st_size) {
64         free(config_buf);
65         config_buf = NULL;
66         return(MR_INTERNAL);
67     }
68     config_buf[st.st_size] = '\0';
69
70     for (p = config_buf; *p; p++)
71       if (*p == '\n') count++;
72     count++;
73     config_keys = (char **)malloc(count * sizeof(char *));
74     config_values = (char **)malloc(count * sizeof(char *));
75     if (config_keys == NULL || config_values == NULL) {
76         free(config_buf);
77         config_buf = NULL;
78         return(MR_NO_MEM);
79     }
80     count = 0;
81     for (p = strtok(config_buf, "\n"); p; p = strtok(NULL, "\n")) {
82         config_keys[count++] = p;
83     }
84     config_keys[count] = NULL;
85     for (count = 0; config_keys[count]; count++) {
86         config_values[count] = "";
87         for (p = config_keys[count]; *p; p++)
88           if (isspace(*p)) {
89               *p++ = '\0';
90               while (*p && isspace(*p)) p++;
91               config_values[count] = p;
92           }
93     }
94     return(MR_SUCCESS);
95 }
96
97
98 /* Given a key, lookup the associated value.  
99  * Returns "" on a key without a value, NULL on a non-existant key.
100  * If a key appears multiple times, successive calls will cycle through
101  * the possible values.
102  */
103
104 char *config_lookup(key)
105 char *key;
106 {
107     static int i = 0;
108     int start;
109
110     if (init() != MR_SUCCESS)
111       return(NULL);
112
113     start = i++;
114     if (config_keys[i] == NULL) i = 0;
115     if (config_keys[i] == NULL) return(NULL);
116
117     do {
118       if (!strcasecmp(key, config_keys[i]))
119         return(config_values[i]);
120       if (config_keys[++i] == NULL)
121         i = 0;
122     } while (i != start);
123
124     if (!strcasecmp(key, config_keys[i]))
125       return(config_values[i]);
126
127     return(NULL);
128 }
This page took 0.044403 seconds and 5 git commands to generate.