1 /* This file is part of Mailfromd.
2    Copyright (C) 2007-2021 Sergey Poznyakoff
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 
21 #include <libmf.h>
22 #include <stdlib.h>
23 #include <mailutils/locker.h>
24 #include <mailutils/alloc.h>
25 
26 
27 char **
config_array_to_argv(mu_config_value_t * val)28 config_array_to_argv (mu_config_value_t *val)
29 {
30   int i, j;
31   int argc;
32   char **argv;
33 
34   argc = val->v.arg.c;
35   argv = mu_calloc (argc + 1, sizeof (argv[0]));
36   for (i = j = 0; i < argc; i++)
37     {
38       if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING) == 0)
39 	argv[j++] = mu_strdup (val->v.arg.v[i].v.string);
40     }
41   argv[j] = NULL;
42   return argv;
43 }
44 
45 char *
config_array_to_string(mu_config_value_t * val)46 config_array_to_string (mu_config_value_t *val)
47 {
48   size_t len = 0;
49   int i;
50   char *str, *p;
51 
52   for (i = 0; i < val->v.arg.c; i++)
53     {
54       if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING))
55 	return NULL;
56       len += strlen (val->v.arg.v[i].v.string) + 1;
57     }
58 
59   str = mu_alloc (len);
60   p = str;
61   for (i = 0; i < val->v.arg.c; i++)
62     {
63       size_t n = strlen (val->v.arg.v[i].v.string);
64       memcpy (p, val->v.arg.v[i].v.string, n);
65       p += n;
66       *p++ = ' ';
67     }
68   str[len-1] = 0;
69   return str;
70 }
71 
72 
73 int
config_cb_timeout(struct timeval * pt,mu_config_value_t * val)74 config_cb_timeout (struct timeval *pt, mu_config_value_t *val)
75 {
76   int rc;
77   const char *endp;
78   time_t t;
79   const char *str;
80   char *alloc_str = NULL;
81 
82   switch (val->type)
83     {
84     case MU_CFG_STRING:
85       str = val->v.string;
86       break;
87 
88     case MU_CFG_ARRAY:
89       str = alloc_str = config_array_to_string (val);
90       if (!str)
91 	return 1;
92       break;
93 
94     case MU_CFG_LIST:
95       mu_error (_("unexpected list"));
96       return 1;
97 
98     default:
99       mu_error (_("INTERNAL ERROR at %s:%d: please report"),
100 		__FILE__, __LINE__);
101       abort();
102     }
103 
104   rc = parse_time_interval (str, &t, &endp);
105   if (rc)
106     mu_error (_("unrecognized time format (near `%s')"), endp);
107   else
108     {
109       pt->tv_usec = 0;
110       pt->tv_sec = t;
111     }
112   free (alloc_str);
113   return 0;
114 }
115 
116 int
config_cb_ignore(void * data,mu_config_value_t * val)117 config_cb_ignore(void *data, mu_config_value_t *val)
118 {
119 	mu_diag_output (MU_DIAG_WARNING,
120 			_("this statement has no effect in %s"),
121 			PACKAGE_STRING);
122 	return 0;
123 }
124 
125 int
config_cb_lock_retry_count(void * data,mu_config_value_t * val)126 config_cb_lock_retry_count(void *data, mu_config_value_t *val)
127 {
128 	int rc;
129 	char *errmsg;
130 	size_t v;
131 
132 	if (mu_cfg_assert_value_type(val, MU_CFG_STRING))
133 		return 1;
134 	rc = mu_str_to_c(val->v.string, mu_c_size, &v, &errmsg);
135 	if (rc) {
136 		mu_error(_("%s: not a valid number"), val->v.string);
137 		free(errmsg);
138 		return 1;
139 	}
140 	mu_locker_set_default_retry_count(v);
141 	return 0;
142 }
143 
144 int
config_cb_lock_retry_timeout(void * data,mu_config_value_t * val)145 config_cb_lock_retry_timeout(void *data, mu_config_value_t *val)
146 {
147 	int rc;
148 	char *errmsg;
149 	time_t v;
150 
151 	rc = mu_str_to_c(val->v.string, mu_c_time, &v, &errmsg);
152 	if (rc) {
153 		mu_error(_("%s: not a valid interval"), val->v.string);
154 		free(errmsg);
155 		return 1;
156 	}
157 	mu_locker_set_default_retry_timeout(v);
158 	return 0;
159 }
160 
161 int
stderr_closed_p()162 stderr_closed_p()
163 {
164 	int fd = dup(0);
165 	if (fd < 0)
166 		return 1;
167 	close(fd);
168 	return fd <= 2;
169 }
170 
171 
172 int
mf_list_compare_string(const void * item,const void * value)173 mf_list_compare_string(const void *item, const void *value)
174 {
175 	return strcmp(item, value);
176 }
177 
178 
179 
180 
181