1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
commit 41283d1359b652c728ca37406a33e62e8541bdda
Author: Andrew Savchenko <bircoph@gmail.com>
Date: Fri Feb 20 21:04:48 2015 +0300
parser: check correctness of str to int conversions.
diff --git a/main.c b/main.c
index 48aee6a..d057489 100644
--- a/main.c
+++ b/main.c
@@ -808,15 +808,33 @@ static int synchandler_arg1(char *arg, size_t arg_len, void *_ctx_p) {
return synchandler_arg(arg, arg_len, _ctx_p, SHARGS_INITIAL);
}
-int parse_customsignals(ctx_t *ctx_p, char *arg) {
+/* strtol wrapper with error checks */
+static inline long xstrtol(const char *str, int *err) {
+ long res;
+ char *endptr;
+
+ res = strtol(str, &endptr, 0);
+ if (errno || *endptr) {
+ error("argument \"%s\" can't be parsed as a number", str);
+ *err = EINVAL;
+ }
+ return res;
+}
+
+static inline int parse_customsignals(ctx_t *ctx_p, char *arg) {
char *ptr = arg, *start = arg;
+ int ret = 0;
unsigned int signal;
do {
switch (*ptr) {
case 0:
case ',':
case ':':
- signal = (unsigned int)atoi(start);
+ signal = (unsigned int)xstrtol(start, &ret);
+ if (ret) {
+ errno = ret;
+ return errno;
+ }
if (signal == 0) {
// flushing the setting
int i = 0;
@@ -883,7 +901,8 @@ int parse_customsignals(ctx_t *ctx_p, char *arg) {
return 0;
}
-int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t paramsource) {
+static int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t paramsource) {
+ int ret = 0;
#ifdef _DEBUG_FORCE
fprintf(stderr, "Force-Debug: parse_parameter(): %i: %i = \"%s\"\n", paramsource, param_id, arg);
#endif
@@ -962,7 +981,7 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
ctx_p->flags[param_id]++;
if (pwd == NULL) {
- ctx_p->uid = (unsigned int)atol(arg);
+ ctx_p->uid = (unsigned int)xstrtol(arg, &ret);
break;
}
@@ -974,7 +993,7 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
ctx_p->flags[param_id]++;
if (grp == NULL) {
- ctx_p->gid = (unsigned int)atol(arg);
+ ctx_p->gid = (unsigned int)xstrtol(arg, &ret);
break;
}
@@ -1028,7 +1047,7 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
ctx_p->flags[param_id]++;
if (pwd == NULL) {
- ctx_p->synchandler_uid = (unsigned int)atol(arg);
+ ctx_p->synchandler_uid = (unsigned int)xstrtol(arg, &ret);
break;
}
@@ -1040,7 +1059,7 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
ctx_p->flags[param_id]++;
if (grp == NULL) {
- ctx_p->synchandler_gid = (unsigned int)atol(arg);
+ ctx_p->synchandler_gid = (unsigned int)xstrtol(arg, &ret);
break;
}
@@ -1233,7 +1252,7 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
ctx_p->pidfile = arg;
break;
case RETRIES:
- ctx_p->retries = (unsigned int)atol(arg);
+ ctx_p->retries = (unsigned int)xstrtol(arg, &ret);
break;
case THREADING: {
char *value, *arg_orig = arg;
@@ -1279,22 +1298,22 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
ctx_p->cluster_mcastipaddr = arg;
break;
case CLUSTERMCASTIPPORT:
- ctx_p->cluster_mcastipport = (uint16_t)atoi(arg);
+ ctx_p->cluster_mcastipport = (uint16_t)xstrtol(arg, &ret);
break;
case CLUSTERTIMEOUT:
- ctx_p->cluster_timeout = (unsigned int)atol(arg);
+ ctx_p->cluster_timeout = (unsigned int)xstrtol(arg, &ret);
break;
case CLUSTERNODENAME:
ctx_p->cluster_nodename = arg;
break;
case CLUSTERHDLMIN:
- ctx_p->cluster_hash_dl_min = (uint16_t)atoi(arg);
+ ctx_p->cluster_hash_dl_min = (uint16_t)xstrtol(arg, &ret);
break;
case CLUSTERHDLMAX:
- ctx_p->cluster_hash_dl_max = (uint16_t)atoi(arg);
+ ctx_p->cluster_hash_dl_max = (uint16_t)xstrtol(arg, &ret);
break;
case CLUSTERSDLMAX:
- ctx_p->cluster_scan_dl_max = (uint16_t)atoi(arg);
+ ctx_p->cluster_scan_dl_max = (uint16_t)xstrtol(arg, &ret);
break;
#endif
case OUTLISTSDIR:
@@ -1334,16 +1353,16 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
break;
}
case SYNCDELAY:
- ctx_p->syncdelay = (unsigned int)atol(arg);
+ ctx_p->syncdelay = (unsigned int)xstrtol(arg, &ret);
break;
case DELAY:
- ctx_p->_queues[QUEUE_NORMAL].collectdelay = (unsigned int)atol(arg);
+ ctx_p->_queues[QUEUE_NORMAL].collectdelay = (unsigned int)xstrtol(arg, &ret);
break;
case BFILEDELAY:
- ctx_p->_queues[QUEUE_BIGFILE].collectdelay = (unsigned int)atol(arg);
+ ctx_p->_queues[QUEUE_BIGFILE].collectdelay = (unsigned int)xstrtol(arg, &ret);
break;
case BFILETHRESHOLD:
- ctx_p->bfilethreshold = (unsigned long)atol(arg);
+ ctx_p->bfilethreshold = (unsigned long)xstrtol(arg, &ret);
break;
case CANCEL_SYSCALLS: {
char *subopts = arg;
@@ -1412,10 +1431,10 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
break;
}
case RSYNCINCLIMIT:
- ctx_p->rsyncinclimit = (unsigned int)atol(arg);
+ ctx_p->rsyncinclimit = (unsigned int)xstrtol(arg, &ret);
break;
case SYNCTIMEOUT:
- ctx_p->synctimeout = (unsigned int)atol(arg);
+ ctx_p->synctimeout = (unsigned int)xstrtol(arg, &ret);
break;
case PREEXITHOOK:
if (strlen(arg)) {
@@ -1611,13 +1630,13 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
if (arg == NULL)
ctx_p->flags[param_id]++;
else
- ctx_p->flags[param_id] = atoi(arg);
+ ctx_p->flags[param_id] = xstrtol(arg, &ret);
#ifdef _DEBUG_FORCE
fprintf(stderr, "Force-Debug: flag %i is set to %i\n", param_id&0xff, ctx_p->flags[param_id]);
#endif
break;
}
- return 0;
+ return ret;
}
int arguments_parse(int argc, char *argv[], struct ctx *ctx_p) {
|