Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
util.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2 -*- */
2 /* Copyright(C) 2010- Brazil
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License version 2.1 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Lesser General Public License for more details.
12 
13  You should have received a copy of the GNU Lesser General Public
14  License along with this library; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <stdint.h>
21 #include <stdarg.h>
22 #include <unistd.h>
23 #include <sys/wait.h>
24 #include <sys/queue.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 
29 #include "util.h"
30 
31 #define DEFAULT_FREQUENCY_THRESHOLD 100
32 #define DEFAULT_CONDITIONAL_PROBABILITY_THRESHOLD 0.2
33 
34 int
35 print_error(const char *format, ...)
36 {
37  int r;
38  va_list l;
39 
40  va_start(l, format);
41  vfprintf(stderr, format, l);
42  r = fprintf(stderr, "\n");
43  fflush(stderr);
44  va_end(l);
45 
46  return r;
47 }
48 
49 int
50 daemonize(void)
51 {
52  pid_t pid;
53 
54  switch (fork()) {
55  case 0:
56  break;
57  case -1:
58  print_error("fork failed.");
59  return -1;
60  default:
61  wait(NULL);
62  _exit(0);
63  }
64  switch ((pid = fork())) {
65  case 0:
66  break;
67  case -1:
68  perror("fork");
69  return -1;
70  default:
71  fprintf(stderr, "%d\n", pid);
72  _exit(0);
73  }
74  {
75  int null_fd = open("/dev/null", O_RDWR, 0);
76  if (null_fd != -1) {
77  dup2(null_fd, 0);
78  dup2(null_fd, 1);
79  dup2(null_fd, 2);
80  if (null_fd > 2) { close(null_fd); }
81  }
82  }
83  return 1;
84 }
85 
86 static uint64_t
87 atouint64_t(const char *s)
88 {
89  uint64_t r;
90  for (r = 0; *s; s++) {
91  r *= 10;
92  r += (*s - '0');
93  }
94  return r;
95 }
96 
97 void
99  struct evkeyvalq *get_args,
100  const char **query, const char **types,
101  const char **client_id, const char **target_name,
102  const char **learn_target_name,
103  const char **callback,
104  uint64_t *millisec,
105  int *frequency_threshold,
106  double *conditional_probability_threshold,
107  int *limit,
108  grn_obj *pass_through_parameters)
109 {
110  struct evkeyval *get;
111 
112  if (query) { *query = NULL; }
113  if (types) { *types = NULL; }
114  if (client_id) { *client_id = NULL; }
115  if (target_name) { *target_name = NULL; }
116  if (learn_target_name) { *learn_target_name = NULL; }
117  if (callback) { *callback = NULL; }
118  if (millisec) { *millisec = 0; }
119  if (frequency_threshold) {
120  *frequency_threshold = DEFAULT_FREQUENCY_THRESHOLD;
121  }
122  if (conditional_probability_threshold) {
123  *conditional_probability_threshold = DEFAULT_CONDITIONAL_PROBABILITY_THRESHOLD;
124  }
125  if (limit) { *limit = -1; }
126 
127  TAILQ_FOREACH(get, get_args, next) {
128  grn_bool is_pass_through_parameter = GRN_FALSE;
129  size_t key_length;
130 
131  key_length = strlen(get->key);
132  switch (key_length) {
133  case 0:
134  break;
135  case 1:
136  switch(get->key[0]) {
137  case 'q':
138  if (query) {
139  *query = get->value;
140  }
141  break;
142  case 't':
143  /* TODO: check types */
144  if (types) {
145  *types = get->value;
146  }
147  break;
148  case 'i':
149  if (client_id) {
150  *client_id = get->value;
151  }
152  break;
153  case 's':
154  if (millisec) {
155  *millisec = atouint64_t(get->value);
156  }
157  break;
158  case 'n':
159  /* TODO: check target_name */
160  if (target_name) {
161  *target_name = get->value;
162  }
163  break;
164  case 'l':
165  if (learn_target_name) {
166  *learn_target_name = get->value;
167  }
168  break;
169  case 'h':
170  if (frequency_threshold) {
171  *frequency_threshold = atoi(get->value);
172  }
173  break;
174  case 'p':
175  if (conditional_probability_threshold) {
176  *conditional_probability_threshold = strtod(get->value, NULL);
177  }
178  break;
179  case 'm':
180  if (limit) {
181  *limit = atoi(get->value);
182  }
183  break;
184  default:
185  is_pass_through_parameter = GRN_TRUE;
186  break;
187  }
188  break;
189  default:
190  switch (get->key[0]) {
191  case 'c':
192  if (!strcmp(get->key, "callback")) {
193  if (callback) {
194  *callback = get->value;
195  }
196  } else {
197  is_pass_through_parameter = GRN_TRUE;
198  }
199  break;
200  default:
201  is_pass_through_parameter = GRN_TRUE;
202  }
203  }
204 
205  if (is_pass_through_parameter && pass_through_parameters) {
206  if (GRN_TEXT_LEN(pass_through_parameters) > 0) {
207  GRN_TEXT_PUTS(ctx, pass_through_parameters, "&");
208  }
209  grn_text_urlenc(ctx, pass_through_parameters, get->key, strlen(get->key));
210  GRN_TEXT_PUTS(ctx, pass_through_parameters, "=");
211  grn_text_urlenc(ctx, pass_through_parameters,
212  get->value, strlen(get->value));
213  }
214  }
215 }