]> git.neil.brown.name Git - metad.git/blob - read_config.c
Full prototype for class methods.
[metad.git] / read_config.c
1
2 #include        "metad.h"
3 #undef NULL
4 #include        <stdio.h>
5 #include        "skip.h"
6
7 /* read the config file
8  *
9  * first mark all services as pending
10  *
11  * then for each line which is not a blank/comment
12  *  strplit and find name/class
13  *  if name already exists:
14  *    if same class, set attributes
15  *    if different class, rename old service and create new
16  *  else
17  *    create new service if remainder parses ok
18  *
19  * if any remaining services are pending, disabled them unless there were errors
20  *
21  */
22
23 int read_config(void *services, char *file)
24 {
25         service_t *serv;
26         char linebuf[1024];
27         FILE *f;
28         int err = 0;
29         static char *lastfile = NULL;
30         if (file) lastfile = file;
31         else file = lastfile;
32
33         for (serv = skip_first(services) ; serv ; serv = skip_next(serv))
34                 (*serv)->pending = 1;
35
36         f = fopen(file, "r");
37         if (f == NULL)
38         {
39                 error("cannot find config file %s", file);
40                 return 1;
41         }
42         while (fgets(linebuf, sizeof(linebuf), f)!= NULL)
43         {
44                 int len = strlen(linebuf);
45                 char **words;
46                 int w;
47
48                 if (len > 1000 && linebuf[len-1] != '\n')
49                 {
50                         error("line too long in config file");
51                         fclose(f);
52                         return 1;
53                 }
54                 if (linebuf[len-1] == '\n') linebuf[--len] = 0;
55
56                 words = strsplit(linebuf, " \t\n");
57                 if (words)
58                 {
59                         for (w=0 ;words[w] ; w++) if (words[w][0]=='#') words[w]=NULL;
60                         if (words[0] && words[1])
61                         {
62                                 /* not a comment */
63                                 service_t *svp = skip_search(services, words[0]);
64                                 service_t sv;
65                                 class_t cl = find_class(words[1]);
66                                 if (svp != NULL)
67                                 {
68                                         if ((*svp)->class != cl)
69                                         {
70                                                 /* different  classes - rename old services */
71                                                 skip_delete(services, words[0]);
72                                                 strcpy(linebuf, words[0]);
73                                                 do { strcat(linebuf, ".old"); } while (skip_search(services, linebuf)!= NULL);
74                                                 free((*svp)->service);
75                                                 (*svp)->service = strdup(linebuf);
76                                                 skip_insert(services, *svp);
77                                                 svp = NULL;
78                                         }
79                                 }
80                                 if (cl == NULL)
81                                 {
82                                         error("unknown class %s", words[1]);
83                                         err ++;
84                                         continue;
85                                 }
86                                 sv = new_service(words[0], cl);
87                                 /* now process options */
88                                 for (w=2 ; words[w] && words[w][0] != '/' ; w++)
89                                 {
90                                         int ok = process_opt(sv, words[w]);
91                                         if (ok == 0)
92                                                 ok = sv->class->c_process_opt(sv, words[w]);
93                                         if (ok <= 0)
94                                         {
95                                                 if (ok == 0)
96                                                         error("unknown option: %s", words[w]);
97                                                 else
98                                                         error("error in option: %s", words[w]);
99                                                 free_service(sv);
100                                                 sv = NULL;
101                                                 err++;
102                                                 break;
103                                         }
104                                 }
105                                 if (sv == NULL) continue;
106                                 if (words[w])
107                                         sv->program = strdup(words[w++]);
108                                 if (words[w])
109                                         sv->args = strlistdup(words+w);
110                                 if (sv->program == NULL)
111                                         error("missing program name for service %s", words[0]), err++;
112                                 else if (sv->args == NULL)
113                                         error("missing program arguments for service %s", words[0]), err++;
114                                 else
115                                 {
116                                         if (svp)
117                                         {
118                                                 proc_t *pp2;
119                                                 service_t sv2 = *svp;
120                                                 sv->enabled = sv2->enabled;
121                                                 sv->proc_list = sv2->proc_list;
122
123                                                 /* change service pointer to the new structure (for aidan) */
124                                                 if (sv->proc_list)
125                                                         for (pp2 = skip_first(sv->proc_list) ; pp2 ; pp2=skip_next(pp2))
126                                                                 (*pp2)->service = sv;
127
128                                                 sv2->proc_list = NULL;
129                                                 sv->class->copy_state(sv2, sv);
130                                                 skip_delete(services, sv2->service);
131                                                 free_service(sv2);
132                                         }
133                                         skip_insert(services, sv);
134                                         sv->class->register_service(sv);
135                                         sv = NULL;
136                                 }
137                                 if (sv) free_service(sv);
138                         }
139                         free(words[-1]);
140                         free(words-1);
141                 }
142         }
143         fclose(f);
144         for (serv = skip_first(services) ; serv ; serv = skip_next(serv))
145                 if ((*serv)->pending)
146                         (*serv)->enabled = 0;
147         return err;
148 }