OpenDNSSEC-enforcer  2.0.2
task.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 #include "scheduler/task.h"
34 #include "duration.h"
35 #include "file.h"
36 #include "log.h"
37 
38 static const char* task_str = "task";
39 
40 typedef struct taskreg taskreg_type;
41 
42 struct taskreg {
43  const char *short_name;
44  const char *long_name;
47 };
48 
49 static taskreg_type taskreg[16];
50 static int ntaskreg = 0;
51 const int NUM_HOW_REG = sizeof(taskreg)/sizeof(taskreg_type);
52 
53 bool task_id_from_long_name(const char *long_name, task_id *pwhat)
54 {
55  int i;
56  for (i=0; i<ntaskreg; ++i) {
57  if (strcmp(taskreg[i].long_name,long_name)==0) {
58  *pwhat = TASK_DYNAMIC_FIRST+i;
59  return true;
60  }
61  }
62  return false;
63 }
64 
65 static const char *task_id_to_short_name(task_id id, const char *def)
66 {
67  if (id >= TASK_DYNAMIC_FIRST && (signed)id-TASK_DYNAMIC_FIRST < ntaskreg) {
68  return taskreg[id-TASK_DYNAMIC_FIRST].short_name;
69  }
70  return def;
71 }
72 
73 static bool task_id_to_how(task_id id, how_type *phow)
74 {
75  if (id >= TASK_DYNAMIC_FIRST && (signed)id-TASK_DYNAMIC_FIRST < ntaskreg) {
76  *phow = taskreg[id-TASK_DYNAMIC_FIRST].how;
77  return true;
78  }
79  return false;
80 }
81 
82 task_id task_register(const char *short_name, const char *long_name,
83  how_type how)
84 {
85  int i;
86 
87  /* update existing registration */
88  for (i=0; i<ntaskreg; ++i) {
89  if (strcmp(long_name, taskreg[i].long_name)==0) {
90  taskreg[i].how = how;
91  return TASK_DYNAMIC_FIRST+i;
92  }
93  }
94 
95  if (ntaskreg >= NUM_HOW_REG) {
96  ods_log_error("Unable to register additional name,how pairs for tasks.");
97  return TASK_NONE;
98  }
99  taskreg[ntaskreg].short_name = short_name;
100  taskreg[ntaskreg].long_name = long_name;
101  taskreg[ntaskreg].how = how;
102  return TASK_DYNAMIC_FIRST+ntaskreg++;
103 }
104 
109 task_type*
110 task_create(task_id what_id, time_t when, const char* who, const char* what,
111  void* context, how_type clean_context)
112 {
113  task_type* task = NULL;
114 
115  if (!who || !context) {
116  ods_log_error("[%s] cannot create: missing context info", task_str);
117  return NULL;
118  }
119  ods_log_assert(who);
120  ods_log_assert(context);
121 
122  task = (task_type*) malloc(sizeof(task_type));
123  if (!task) {
124  ods_log_error("[%s] cannot create: malloc failed", task_str);
125  return NULL;
126  }
127  task->what = what_id;
128  task->interrupt = TASK_NONE;
129  task->halted = TASK_NONE;
130  task->when = when;
131  task->backoff = 0;
132  task->who = strdup(who);
133  task->dname = ldns_dname_new_frm_str(what);
134  task->flush = 0;
135  task->context = context;
136  task->clean_context = clean_context;
137  if (!task_id_to_how(what_id, &task->how))
138  task->how = NULL; /* Standard task */
139  return task;
140 }
141 
146 void
148 {
149  if (!task) {
150  return;
151  }
152  if (task->dname) {
153  ldns_rdf_deep_free(task->dname);
154  task->dname = NULL;
155  }
156  if (task->clean_context && task->context) {
157  (void)task->clean_context(task);
158  task->context = NULL;
159  }
160  free(task->who);
161  free(task);
162 }
163 
164 
169 int
170 task_compare(const void* a, const void* b)
171 {
172  task_type* x = (task_type*)a;
173  task_type* y = (task_type*)b;
174 
175  ods_log_assert(x);
176  ods_log_assert(y);
177 
178  /* If a task is set to flush, it should go in front. */
179  if (x->flush != y->flush) {
180  return y->flush - x->flush;
181  }
182 
183  /* order task on time, dname */
184  if (x->when != y->when) {
185  return (int) x->when - y->when;
186  }
187  return ldns_dname_compare((const void*) x->dname,
188  (const void*) y->dname);
189 }
190 
194 int
195 task_compare_name(const void* a, const void* b)
196 {
197  task_type* x = (task_type*)a;
198  task_type* y = (task_type*)b;
199  ods_log_assert(x);
200  ods_log_assert(y);
201  /* order task on time, dname */
202  return ldns_dname_compare((const void*) x->dname,
203  (const void*) y->dname);
204 }
205 
206 
211 const char*
212 task_what2str(int what)
213 {
214  switch (what) {
215  case TASK_NONE:
216  return "do nothing with";
217  case TASK_SIGNCONF:
218  return "load signconf for";
219  case TASK_READ:
220  return "read";
221  case TASK_NSECIFY:
222  return "nsecify";
223  case TASK_SIGN:
224  return "sign";
225  case TASK_AUDIT:
226  return "audit";
227  case TASK_WRITE:
228  return "write";
229  default:
230  return task_id_to_short_name(what, "???");
231  }
232 }
233 
234 
239 const char*
240 task_who2str(const char* who)
241 {
242  if (who) {
243  return who;
244  }
245  return "(null)";
246 }
247 
248 
253 char*
254 task2str(task_type* task, char* buftask)
255 {
256  char ctimebuf[32]; /* at least 26 according to docs */
257  time_t now = time_now();
258  char* strtime = NULL;
259  char* strtask = NULL;
260 
261  if (task) {
262  if (task->flush) {
263  strtime = ctime_r(&now,ctimebuf);
264  } else {
265  strtime = ctime_r(&task->when,ctimebuf);
266  }
267  if (strtime) {
268  strtime[strlen(strtime)-1] = '\0';
269  }
270  if (buftask) {
271  (void)snprintf(buftask, ODS_SE_MAXLINE, "On %s I will [%s] %s"
272  "\n", strtime?strtime:"(null)", task_what2str(task->what),
273  task_who2str(task->who));
274  return buftask;
275  } else {
276  strtask = (char*) calloc(ODS_SE_MAXLINE, sizeof(char));
277  snprintf(strtask, ODS_SE_MAXLINE, "On %s I will [%s] %s\n",
278  strtime?strtime:"(null)", task_what2str(task->what),
279  task_who2str(task->who));
280  return strtask;
281  }
282  }
283  return NULL;
284 }
285 
286 
291 task_type *
293 {
294  if (task->how)
295  return task->how(task);
296 
297  task_cleanup(task);
298  return NULL;
299 }
Definition: task.h:42
time_t when
Definition: task.h:63
task_id interrupt
Definition: task.h:61
Definition: task.c:42
char * who
Definition: task.h:66
int flush
Definition: task.h:65
time_t backoff
Definition: task.h:64
void * context
Definition: task.h:68
void ods_log_error(const char *format,...)
Definition: log.c:69
bool task_id_from_long_name(const char *long_name, task_id *pwhat)
Definition: task.c:53
Definition: task.h:47
task_type *(* how)(task_type *task)
Definition: task.h:69
enum task_id_enum task_id
Definition: task.h:53
ldns_rdf * dname
Definition: task.h:67
Definition: task.h:45
task_type * task_perform(task_type *task)
Definition: task.c:292
task_id halted
Definition: task.h:62
void task_cleanup(task_type *task)
Definition: task.c:147
const char * short_name
Definition: task.c:43
const int NUM_HOW_REG
Definition: task.c:51
const char * task_what2str(int what)
Definition: task.c:212
task_type *(* clean_context)(task_type *task)
Definition: task.h:70
const char * task_who2str(const char *who)
Definition: task.c:240
how_type clean
Definition: task.c:46
task_id what
Definition: task.h:60
task_id task_register(const char *short_name, const char *long_name, how_type how)
Definition: task.c:82
task_type * task_create(task_id what_id, time_t when, const char *who, const char *what, void *context, how_type clean_context)
Definition: task.c:110
how_type how
Definition: task.c:45
int task_compare(const void *a, const void *b)
Definition: task.c:170
char * task2str(task_type *task, char *buftask)
Definition: task.c:254
int task_compare_name(const void *a, const void *b)
Definition: task.c:195
task_type *(* how_type)(task_type *task)
Definition: task.h:74
const char * long_name
Definition: task.c:44