Bug Summary

File:cli/src/cli-cmd.c
Location:line 85, column 33
Description:Dereference of null pointer (loaded from variable 'status')

Annotated Source Code

1/*
2 Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13#include <stdint.h>
14#include <pthread.h>
15
16#ifndef _CONFIG_H
17#define _CONFIG_H
18#include "config.h"
19#endif
20
21#include "cli.h"
22#include "cli-cmd.h"
23#include "cli-mem-types.h"
24#include "protocol-common.h"
25
26#include <fnmatch.h>
27
28static int cmd_done;
29static int cmd_sent;
30static pthread_cond_t cond = PTHREAD_COND_INITIALIZER{ { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } };
31static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, { 0 } } };
32static pthread_cond_t conn = PTHREAD_COND_INITIALIZER{ { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } };
33static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, { 0 } } };
34
35int cli_op_ret = 0;
36int connected = 0;
37
38int cli_cmd_log_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
39 const char **words, int wordcount);
40
41static unsigned
42cli_cmd_needs_connection (struct cli_cmd_word *word)
43{
44 if (!strcasecmp ("quit", word->word))
45 return 0;
46
47 if (!strcasecmp ("help", word->word))
48 return 0;
49
50 if (!strcasecmp ("getwd", word->word))
51 return 1;
52
53 if (!strcasecmp ("exit", word->word))
54 return 0;
55
56 return CLI_DEFAULT_CONN_TIMEOUT120;
57}
58
59int
60cli_cmd_status_reset (void)
61{
62 int ret = 0;
63
64 ret = cli_cmd_lock ();
65 {
66 if (ret == 0) {
67 cmd_sent = 0;
68 cmd_done = 0;
69 }
70 }
71 ret = cli_cmd_unlock ();
72 return ret;
73
74}
75
76int
77cli_cmd_sent_status_get (int *status)
78{
79 int ret = 0;
80 GF_ASSERT (status)do { if (!(status)) { do { do { if (0) printf ("Assertion failed: "
"status"); } while (0); _gf_log_callingfn ("", "cli-cmd.c", __FUNCTION__
, 80, GF_LOG_ERROR, "Assertion failed: " "status"); } while (
0); } } while (0)
;
1
Within the expansion of the macro 'GF_ASSERT':
a
Assuming 'status' is null
81
82 ret = cli_cmd_lock ();
83 {
84 if (ret == 0)
2
Taking true branch
85 *status = cmd_sent;
3
Dereference of null pointer (loaded from variable 'status')
86 }
87 ret = cli_cmd_unlock ();
88 return ret;
89}
90
91int
92cli_cmd_process (struct cli_state *state, int argc, char **argv)
93{
94 int ret = 0;
95 struct cli_cmd_word *word = NULL((void*)0);
96 struct cli_cmd_word *next = NULL((void*)0);
97 int i = 0;
98
99 word = &state->tree.root;
100
101 if (!argc)
102 return 0;
103
104 for (i = 0; i < argc; i++) {
105 next = cli_cmd_nextword (word, argv[i]);
106
107 word = next;
108 if (!word)
109 break;
110
111 if (word->cbkfn)
112 break;
113 }
114
115 if (!word) {
116 cli_out ("unrecognized word: %s (position %d)",do { do { if (0) printf ("unrecognized word: %s (position %d)"
, argv[i], i); } while (0); _cli_out("unrecognized word: %s (position %d)"
, argv[i], i); } while (0)
117 argv[i], i)do { do { if (0) printf ("unrecognized word: %s (position %d)"
, argv[i], i); } while (0); _cli_out("unrecognized word: %s (position %d)"
, argv[i], i); } while (0)
;
118 return -1;
119 }
120
121 if (!word->cbkfn) {
122 cli_out ("unrecognized command")do { do { if (0) printf ("unrecognized command"); } while (0)
; _cli_out("unrecognized command"); } while (0)
;
123 return -1;
124 }
125
126 if ( strcmp (word->word,"help")==0 )
127 goto callback;
128
129 state->await_connected = cli_cmd_needs_connection (word);
130
131 ret = cli_cmd_await_connected (state->await_connected);
132 if (ret) {
133 cli_out ("Connection failed. Please check if gluster "do { do { if (0) printf ("Connection failed. Please check if gluster "
"daemon is operational."); } while (0); _cli_out("Connection failed. Please check if gluster "
"daemon is operational."); } while (0)
134 "daemon is operational.")do { do { if (0) printf ("Connection failed. Please check if gluster "
"daemon is operational."); } while (0); _cli_out("Connection failed. Please check if gluster "
"daemon is operational."); } while (0)
;
135 gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret)do { do { if (0) printf ("Exiting with: %d", ret); } while (0
); _gf_log ("", "cli-cmd.c", __FUNCTION__, 135, GF_LOG_INFO, "Exiting with: %d"
, ret); } while (0)
;
136 exit (ret);
137 }
138
139callback:
140 ret = word->cbkfn (state, word, (const char **)argv, argc);
141 (void) cli_cmd_status_reset ();
142 return ret;
143}
144
145int
146cli_cmd_input_token_count (const char *text)
147{
148 int count = 0;
149 const char *trav = NULL((void*)0);
150 int is_spc = 1;
151
152 for (trav = text; *trav; trav++) {
153 if (*trav == ' ') {
154 is_spc = 1;
155 } else {
156 if (is_spc) {
157 count++;
158 is_spc = 0;
159 }
160 }
161 }
162
163 return count;
164}
165
166
167int
168cli_cmd_process_line (struct cli_state *state, const char *text)
169{
170 int count = 0;
171 char **tokens = NULL((void*)0);
172 char **tokenp = NULL((void*)0);
173 char *token = NULL((void*)0);
174 char *copy = NULL((void*)0);
175 char *saveptr = NULL((void*)0);
176 int i = 0;
177 int ret = -1;
178
179 count = cli_cmd_input_token_count (text);
180
181 tokens = calloc (count + 1, sizeof (*tokens));
182 if (!tokens)
183 return -1;
184
185 copy = strdup (text);
186 if (!copy)
187 goto out;
188
189 tokenp = tokens;
190
191 for (token = strtok_r (copy, " \t\r\n", &saveptr); token;
192 token = strtok_r (NULL((void*)0), " \t\r\n", &saveptr)) {
193 *tokenp = strdup (token);
194
195 if (!*tokenp)
196 goto out;
197 tokenp++;
198 i++;
199
200 }
201
202 ret = cli_cmd_process (state, count, tokens);
203out:
204 free (copy);
205
206 if (tokens)
207 cli_cmd_tokens_destroy (tokens);
208
209 return ret;
210}
211
212
213int
214cli_cmds_register (struct cli_state *state)
215{
216 int ret = 0;
217
218 ret = cli_cmd_volume_register (state);
219 if (ret)
220 goto out;
221
222 ret = cli_cmd_probe_register (state);
223 if (ret)
224 goto out;
225
226 ret = cli_cmd_system_register (state);
227 if (ret)
228 goto out;
229
230 ret = cli_cmd_misc_register (state);
231 if (ret)
232 goto out;
233
234#ifdef HAVE_BD_XLATOR
235 ret = cli_cmd_bd_register (state);
236 if (ret)
237 goto out;
238#endif
239out:
240 return ret;
241}
242
243int
244cli_cmd_cond_init ()
245{
246
247 pthread_mutex_init (&cond_mutex, NULL((void*)0));
248 pthread_cond_init (&cond, NULL((void*)0));
249
250 pthread_mutex_init (&conn_mutex, NULL((void*)0));
251 pthread_cond_init (&conn, NULL((void*)0));
252
253 return 0;
254}
255
256int
257cli_cmd_lock ()
258{
259 pthread_mutex_lock (&cond_mutex);
260 return 0;
261}
262
263int
264cli_cmd_unlock ()
265{
266 pthread_mutex_unlock (&cond_mutex);
267 return 0;
268}
269
270static void
271seconds_from_now (unsigned secs, struct timespec *ts)
272{
273 struct timeval tv = {0,};
274
275 gettimeofday (&tv, NULL((void*)0));
276
277 ts->tv_sec = tv.tv_sec + secs;
278 ts->tv_nsec = tv.tv_usec * 1000;
279}
280
281int
282cli_cmd_await_response (unsigned time)
283{
284 struct timespec ts = {0,};
285 int ret = 0;
286
287 cli_op_ret = -1;
288
289 seconds_from_now (time, &ts);
290 while (!cmd_done && !ret) {
291 ret = pthread_cond_timedwait (&cond, &cond_mutex,
292 &ts);
293 }
294
295 cmd_done = 0;
296
297 if (ret)
298 return ret;
299
300 return cli_op_ret;
301}
302
303int
304cli_cmd_broadcast_response (int32_t status)
305{
306
307 pthread_mutex_lock (&cond_mutex);
308 {
309 if (!cmd_sent)
310 goto out;
311 cmd_done = 1;
312 cli_op_ret = status;
313 pthread_cond_broadcast (&cond);
314 }
315
316
317out:
318 pthread_mutex_unlock (&cond_mutex);
319 return 0;
320}
321
322int32_t
323cli_cmd_await_connected (unsigned conn_timo)
324{
325 int32_t ret = 0;
326 struct timespec ts = {0,};
327
328 if (!conn_timo)
329 return 0;
330
331 pthread_mutex_lock (&conn_mutex);
332 {
333 seconds_from_now (conn_timo, &ts);
334 while (!connected && !ret) {
335 ret = pthread_cond_timedwait (&conn, &conn_mutex,
336 &ts);
337 }
338 }
339 pthread_mutex_unlock (&conn_mutex);
340
341
342 return ret;
343}
344
345int32_t
346cli_cmd_broadcast_connected ()
347{
348 pthread_mutex_lock (&conn_mutex);
349 {
350 connected = 1;
351 pthread_cond_broadcast (&conn);
352 }
353
354 pthread_mutex_unlock (&conn_mutex);
355
356 return 0;
357}
358
359int
360cli_cmd_submit (void *req, call_frame_t *frame,
361 rpc_clnt_prog_t *prog,
362 int procnum, struct iobref *iobref,
363 xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
364{
365 int ret = -1;
366 unsigned timeout = 0;
367
368 timeout = (GLUSTER_CLI_PROFILE_VOLUME == procnum) ?
369 CLI_TOP_CMD_TIMEOUT600 : CLI_DEFAULT_CMD_TIMEOUT120;
370
371 cli_cmd_lock ();
372 cmd_sent = 0;
373 ret = cli_submit_request (req, frame, prog,
374 procnum, NULL((void*)0), this, cbkfn, xdrproc);
375
376 if (!ret) {
377 cmd_sent = 1;
378 ret = cli_cmd_await_response (timeout);
379 }
380
381 cli_cmd_unlock ();
382
383 gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log
("cli", "cli-cmd.c", __FUNCTION__, 383, GF_LOG_DEBUG, "Returning %d"
, ret); } while (0)
;
384 return ret;
385}