]> git.neil.brown.name Git - metad.git/blob - daemon.c
Assorted reformating
[metad.git] / daemon.c
1
2 #include        "metad.h"
3
4 typedef struct daemon_opts
5 {
6         int min;
7         int period;
8         time_t last_start;
9 } *daemon_t;
10
11 #define c(sv) ((daemon_t)((sv)->classinfo))
12
13 static int daemon_opt(service_t sv, char *opt)
14 {
15         /* understand min= period= */
16         if (strncmp(opt, "min=", 4)==0) {
17                 c(sv)->min = atoi(opt+4);
18                 return 1;
19         }
20         if (strncmp(opt, "period=", 7) == 0) {
21                 char *cp = opt+7;
22                 int num = atoi(cp);
23                 if (num==0) num=1;
24                 while (isdigit(*cp)) cp++;
25                 switch(*cp) {
26                 case 0: break;
27                 case 's': break;
28                 case 'm': num *= 60; break;
29                 case 'h': num *= 3600 ; break;
30                 case 'd': num *= 24*3600 ; break;
31                 default: error("bad period specifier, %s", opt); break;
32                 }
33                 c(sv)->period = num;
34                 return 1;
35         }
36         return 0;
37 }
38
39
40 static void daemon_register(service_t sv)
41 {
42         /* nothing to do.. */
43         c(sv)->last_start = 0;
44 }
45
46 static void daemon_unregister(service_t sv)
47 {
48         /* nothing to do... */
49 }
50
51 static int daemon_prefork(service_t sv)
52 {
53         return 0;
54 }
55
56 static void daemon_check(service_t sv)
57 {
58         /* make sure min are running, and watch for next period */
59         char *env[3];
60         env[0] = "METAD_REASON=min";
61         env[1] = "METAD_ARG=";
62         env[2] = NULL;
63         while (c(sv)->min > 0 && count_procs(sv) < c(sv)->min)
64                 if (new_proc(sv, env)<=0)
65                         break;
66
67         if (c(sv)->period > 0 &&
68             c(sv)->last_start + c(sv)->period <= time(0)) {
69                 env[0] = "METAD_REASON=period";
70                 new_proc(sv, env);
71                 c(sv)->last_start = time(0); /* even if it didn't start, we tried */
72         }
73         if (c(sv)->period > 0)
74                 waituntil(c(sv)->last_start + c(sv)->period);
75 }
76
77 static void daemon_init(service_t to)
78 {
79         /* create ->classinfo with defaults */
80         daemon_t n;
81
82         n = (daemon_t)malloc(sizeof(struct daemon_opts));
83         n->min = 0;
84         n->period = 0;
85         n->last_start = 0;
86         to->classinfo = n;
87 }
88
89 static void daemon_copy(service_t from, service_t to)
90 {
91         /* copy the 'state' classinfo - last_start */
92
93         c(to)->last_start = c(from)->last_start;
94 }
95
96 static void daemon_freestate(service_t sv)
97 {
98         free(sv->classinfo);
99 }
100
101
102 static void daemon_newparent(service_t sv, proc_t p)
103 {
104         c(sv)->last_start = time(0);
105 }
106
107 static void daemon_newchild(service_t sv)
108 {
109 }
110
111 static void daemon_send(service_t sv)
112 {
113         /* send min, period, last_start */
114         send_byte(1); /* daemon */
115         send_int(c(sv)->min);
116         send_int(c(sv)->period);
117         send_int(c(sv)->last_start);
118 }
119
120 struct class daemon_class = {
121         .class          = "daemon",
122         .c_process_opt  = daemon_opt,
123         .register_service = daemon_register,
124         .c_check_service= daemon_check,
125         .init_state     = daemon_init,
126         .copy_state     = daemon_copy,
127         .free_state     = daemon_freestate,
128         .send_class     = daemon_send,
129         .disable_service= daemon_unregister,
130         .new_parent     = daemon_newparent,
131         .new_child      = daemon_newchild,
132         .prefork        = daemon_prefork,
133 };