source: trunk/third/moira/update/config.c @ 24319

Revision 24319, 3.4 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: config.c 3956 2010-01-05 20:56:56Z zacheiss $
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 * Copyright (C) 1992-1998 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 <moira.h>
15#include "update_server.h"
16
17#include <sys/stat.h>
18
19#include <ctype.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/update/config.c $ $Id: config.c 3956 2010-01-05 20:56:56Z zacheiss $");
28
29/* Variables currently supported:
30 * chroot directory     daemon will run chrooted to this directory
31 * user username        daemon will run with this user's uid
32 * port portname        daemon will listen on this port number
33 * nofork               server stays in foreground & logs to stdout
34 * auth krbname         this user is authorized to connect
35 * noclobber            will not overwrite existing files
36 * noexec               will not execute instructions received
37 */
38
39static char *config_buf = NULL;
40static char **config_keys, **config_values;
41
42static int init(void)
43{
44  int fd, count = 0;
45  struct stat st;
46  char *p, *start;
47
48  /* Only execute once */
49  if (config_buf)
50    return MR_SUCCESS;
51
52  fd = open(CONFIG_FILE, O_RDONLY, 0);
53  if (fd < 0)
54    {
55      config_buf = "";
56      config_keys = malloc(sizeof(char *) * 2);
57      if (!config_keys)
58        return ENOMEM;
59      config_keys[0] = config_keys[1] = NULL;
60      return MR_SUCCESS;
61    }
62
63  if (fstat(fd, &st) < 0)
64    return MR_INTERNAL;
65
66  config_buf = malloc(st.st_size + 2);
67  if (!config_buf)
68    return ENOMEM;
69
70  if (read(fd, config_buf, st.st_size) < st.st_size)
71    {
72      free(config_buf);
73      config_buf = NULL;
74      return MR_INTERNAL;
75    }
76  config_buf[st.st_size] = '\0';
77
78  for (p = config_buf; *p; p++)
79    {
80      if (*p == '\n')
81        count++;
82    }
83  count++;
84  config_keys = malloc(count * sizeof(char *));
85  config_values = malloc(count * sizeof(char *));
86  if (!config_keys || !config_values)
87    {
88      free(config_buf);
89      free(config_keys);
90      free(config_values);
91      config_buf = NULL;
92      return ENOMEM;
93    }
94
95  count = 0;
96  for (p = strtok(config_buf, "\n"); p; p = strtok(NULL, "\n"))
97    config_keys[count++] = p;
98  config_keys[count] = NULL;
99
100  for (count = 0; config_keys[count]; count++)
101    {
102      config_values[count] = "";
103      for (p = config_keys[count]; *p; p++)
104        {
105          if (isspace(*p))
106            {
107              *p++ = '\0';
108              while (*p && isspace(*p))
109                p++;
110              config_values[count] = p;
111            }
112        }
113    }
114  return MR_SUCCESS;
115}
116
117
118/* Given a key, lookup the associated value.
119 * Returns "" on a key without a value, NULL on a non-existant key.
120 * If a key appears multiple times, successive calls will cycle through
121 * the possible values.
122 */
123
124char *config_lookup(char *key)
125{
126  static int i = 0;
127  int start;
128
129  if (init() != MR_SUCCESS)
130    return NULL;
131
132  start = i++;
133  if (!config_keys[i])
134    i = 0;
135  if (!config_keys[i])
136    return NULL;
137
138  do
139    {
140      if (!strcasecmp(key, config_keys[i]))
141        return config_values[i];
142      if (!config_keys[++i])
143        i = 0;
144    }
145  while (i != start);
146
147  if (!strcasecmp(key, config_keys[i]))
148    return config_values[i];
149
150  return NULL;
151}
Note: See TracBrowser for help on using the repository browser.