• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #5022

14 Apr 2026 05:32AM UTC coverage: 72.278% (-0.01%) from 72.291%
#5022

push

travis-ci

web-flow
merge: from main to3.0 branch #35128

74 of 97 new or added lines in 12 files covered. (76.29%)

555 existing lines in 127 files now uncovered.

257556 of 356343 relevant lines covered (72.28%)

133355051.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.56
/tools/shell/src/shellArguments.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#include "shellInt.h"
17
#include "../../inc/pub.h"
18
char   configDirShell[PATH_MAX] = {0};
19

20
#define TAOS_CONSOLE_PROMPT_CONTINUE "   -> "
21

22
#define SHELL_HOST     "The server FQDN to connect. The default host is localhost."
23
#define SHELL_PORT     "The TCP/IP port number to use for the connection."
24
#define SHELL_USER     "The user name to use when connecting to the server."
25
#define SHELL_PASSWORD "The password to use when connecting to the server."
26
#define SHELL_TOKEN    "The token to use when connecting to the server."
27
#define SHELL_AUTH     "The auth string to use when connecting to the server."
28
#define SHELL_GEN_AUTH "Generate auth string from password."
29
#define SHELL_CFG_DIR  "Configuration directory."
30
#define SHELL_DMP_CFG  "Dump configuration."
31
#define SHELL_CMD      "Commands to run without enter the shell."
32
#define SHELL_RAW_TIME "Output time as uint64_t."
33
#define SHELL_FILE     "Script to run without enter the shell."
34
#define SHELL_DB       "Database to use when connecting to the server."
35
#define SHELL_CHECK    "Check the service status."
36
#define SHELL_STARTUP  "Check the details of the service status."
37
#define SHELL_WIDTH    "Set the default binary display width, default is 30."
38
#define SHELL_NET_ROLE "Net role when network connectivity test, options: client|server."
39
#define SHELL_PKT_LEN  "Packet length used for net test, default is 1024 bytes."
40
#define SHELL_PKT_NUM  "Packet numbers used for net test, default is 100."
41
#define SHELL_BI_MODE  "Set BI mode"
42
#define SHELL_BINARY_AS_HEX "Display BINARY strings containing non-printable bytes in hexadecimal notation (0x...). Disabled by default."
43
#define SHELL_VERSION  "Print program version."
44
#define SHELL_DSN      "Use dsn to connect to the cloud server or to a remote server which provides WebSocket connection."
45
#define SHELL_TIMEOUT  "Set the timeout for WebSocket query in seconds, default is 30."
46
#define SHELL_LOG_OUTPUT                                                                                              \
47
  "Specify log output. Options:\n\r\t\t\t     stdout, stderr, /dev/null, <directory>, <directory>/<filename>, "       \
48
  "<filename>\n\r\t\t\t     * If OUTPUT contains an absolute directory, logs will be stored in that directory "       \
49
  "instead of logDir.\n\r\t\t\t     * If OUTPUT contains a relative directory, logs will be stored in the directory " \
50
  "combined with logDir and the relative directory."
51

52
#ifdef WEBSOCKET
53
#define SHELL_DRIVER_DEFAULT "0." // todo simon -> 1
54
#else
55
#define SHELL_DRIVER_DEFAULT "0."
56
#endif
57

58
static int32_t shellParseSingleOpt(int32_t key, char *arg);
59

60
void shellPrintHelp() {
×
61
  char indent[] = "  ";
×
62
  (void)printf("Usage: %s [OPTION...] \r\n\r\n", CUS_PROMPT);
×
63
  (void)printf("%s%s%s%s\r\n", indent, "-a,", indent, SHELL_AUTH);
×
64
  (void)printf("%s%s%s%s\r\n", indent, "-A,", indent, SHELL_GEN_AUTH);
×
65
  (void)printf("%s%s%s%s\r\n", indent, "-B,", indent, SHELL_BI_MODE);
×
NEW
66
  (void)printf("%s%s%s%s\r\n", indent, "-H,", indent, SHELL_BINARY_AS_HEX);
×
67
  (void)printf("%s%s%s%s\r\n", indent, "-c,", indent, SHELL_CFG_DIR);
×
68
  (void)printf("%s%s%s%s\r\n", indent, "-C,", indent, SHELL_DMP_CFG);
×
69
  (void)printf("%s%s%s%s\r\n", indent, "-d,", indent, SHELL_DB);
×
70
  (void)printf("%s%s%s%s\r\n", indent, "-f,", indent, SHELL_FILE);
×
71
  (void)printf("%s%s%s%s\r\n", indent, "-h,", indent, SHELL_HOST);
×
72
  (void)printf("%s%s%s%s\r\n", indent, "-k,", indent, SHELL_CHECK);
×
73
  (void)printf("%s%s%s%s\r\n", indent, "-l,", indent, SHELL_PKT_LEN);
×
74
  (void)printf("%s%s%s%s\r\n", indent, "-n,", indent, SHELL_NET_ROLE);
×
75
  (void)printf("%s%s%s%s\r\n", indent, "-N,", indent, SHELL_PKT_NUM);
×
76
#if defined(LINUX)
77
  (void)printf("%s%s%s%s\r\n", indent, "-o,", indent, SHELL_LOG_OUTPUT);
×
78
#endif
79
  (void)printf("%s%s%s%s\r\n", indent, "-p,", indent, SHELL_PASSWORD);
×
80
#ifdef TD_ENTERPRISE
81
  (void)printf("%s%s%s%s\r\n", indent, "-q,", indent, SHELL_TOKEN);
×
82
#endif
83
  (void)printf("%s%s%s%s\r\n", indent, "-P,", indent, SHELL_PORT);
×
84
  (void)printf("%s%s%s%s\r\n", indent, "-r,", indent, SHELL_RAW_TIME);
×
85
  (void)printf("%s%s%s%s\r\n", indent, "-s,", indent, SHELL_CMD);
×
86
  (void)printf("%s%s%s%s\r\n", indent, "-t,", indent, SHELL_STARTUP);
×
87
  (void)printf("%s%s%s%s\r\n", indent, "-u,", indent, SHELL_USER);
×
88
  (void)printf("%s%s%s%s\r\n", indent, "-E,", indent, OLD_DSN_DESC);
×
89
  (void)printf("%s%s%s%s\r\n", indent, "-T,", indent, SHELL_TIMEOUT);
×
90
  (void)printf("%s%s%s%s\r\n", indent, "-w,", indent, SHELL_WIDTH);
×
91
  (void)printf("%s%s%s%s\r\n", indent, "-V,", indent, SHELL_VERSION);
×
92
  (void)printf("%s%s%s%s\r\n", indent, "-X,", indent, DSN_DESC);
×
93
  (void)printf("%s%s%s%s\r\n", indent, "-Z,", indent, DRIVER_DESC);
×
94

95
#ifdef CUS_EMAIL
96
  (void)printf("\r\n\r\nReport bugs to %s.\r\n", CUS_EMAIL);
×
97
#else
98
  (void)printf("\r\n\r\nReport bugs to %s.\r\n", "support@taosdata.com");
99
#endif
100
}
×
101

102
#if defined(LINUX) && !defined(TD_ASTRA)
103
#include <argp.h>
104
#ifdef _ALPINE
105
#include <termios.h>
106
#else
107
#include <termio.h>
108
#endif
109

110
const char *argp_program_version = td_version;
111
#ifdef CUS_EMAIL
112
const char *argp_program_bug_address = CUS_EMAIL;
113
#else
114
const char *argp_program_bug_address = "support@taosdata.com";
115
#endif
116

117
static struct argp_option shellOptions[] = {
118
    {"host", 'h', "HOST", 0, SHELL_HOST},
119
    {"port", 'P', "PORT", 0, SHELL_PORT},
120
    {"user", 'u', "USER", 0, SHELL_USER},
121
    {0, 'p', 0, 0, SHELL_PASSWORD},
122
#ifdef TD_ENTERPRISE
123
    {0, 'q', 0, 0, SHELL_TOKEN},
124
#endif
125
    {"auth", 'a', "AUTH", 0, SHELL_AUTH},
126
    {"generate-auth", 'A', 0, 0, SHELL_GEN_AUTH},
127
    {"config-dir", 'c', "DIR", 0, SHELL_CFG_DIR},
128
    {"dump-config", 'C', 0, 0, SHELL_DMP_CFG},
129
    {"commands", 's', "COMMANDS", 0, SHELL_CMD},
130
    {"raw-time", 'r', 0, 0, SHELL_RAW_TIME},
131
    {"file", 'f', "FILE", 0, SHELL_FILE},
132
    {"database", 'd', "DATABASE", 0, SHELL_DB},
133
    {"check", 'k', 0, 0, SHELL_CHECK},
134
    {"startup", 't', 0, 0, SHELL_STARTUP},
135
    {"display-width", 'w', "WIDTH", 0, SHELL_WIDTH},
136
    {"netrole", 'n', "NETROLE", 0, SHELL_NET_ROLE},
137
    {"pktlen", 'l', "PKTLEN", 0, SHELL_PKT_LEN},
138
    {"cloud-dsn", 'E', "DSN", 0, OLD_DSN_DESC},
139
    {"timeout", 'T', "SECONDS", 0, SHELL_TIMEOUT},
140
    {"pktnum", 'N', "PKTNUM", 0, SHELL_PKT_NUM},
141
    {"bimode", 'B', 0, 0, SHELL_BI_MODE},
142
    {"binary-as-hex", 'H', 0, 0, SHELL_BINARY_AS_HEX},
143
    {"log-output", 'o', "OUTPUT", 0, SHELL_LOG_OUTPUT},
144
    {"dsn", 'X', "DSN", 0, DSN_DESC},
145
    {DRIVER_OPT, 'Z', "DRIVER", 0, DRIVER_DESC},
146
    {0},
147
};
148

149
static error_t shellParseOpt(int32_t key, char *arg, struct argp_state *state) { return shellParseSingleOpt(key, arg); }
8,518,267✔
150

151
static struct argp shellArgp = {shellOptions, shellParseOpt, "", ""};
152

153
static int32_t shellParseArgsUseArgp(int argc, char *argv[]) {
1,395,910✔
154
  argp_program_version = shell.info.programVersion;
1,395,910✔
155
  error_t err = argp_parse(&shellArgp, argc, argv, 0, 0, &shell.args);
1,395,910✔
156
  return (err != 0);
1,395,198✔
157
}
158

159
#endif
160

161
#ifndef ARGP_ERR_UNKNOWN
162
#define ARGP_ERR_UNKNOWN E2BIG
163
#endif
164

165
static int32_t shellParseSingleOpt(int32_t key, char *arg) {
8,518,267✔
166
  SShellArgs *pArgs = &shell.args;
8,518,267✔
167

168
  switch (key) {
8,518,267✔
169
    case 'h':
898✔
170
      pArgs->host = arg;
898✔
171
      break;
898✔
172
    case 'P':
790✔
173
      pArgs->port = atoi(arg);
790✔
174
      if (pArgs->port == 0) {
790✔
175
        pArgs->port = -1;
161✔
176
      } else {
177
        pArgs->port_inputted = true;
629✔
178
      }
179
      break;
790✔
180
    case 'u':
3,717✔
181
      pArgs->user = arg;
3,717✔
182
      break;
3,717✔
183
    case 'p':
3,446✔
184
      break;
3,446✔
185
    case 'q':
2,272✔
186
      break;
2,272✔
187
    case 'a':
172✔
188
      pArgs->auth = arg;
172✔
189
      break;
172✔
190
    case 'A':
44✔
191
      pArgs->is_gen_auth = true;
44✔
192
      break;
44✔
193
    case 'B':
297✔
194
      pArgs->is_bi_mode = true;
297✔
195
      break;
297✔
196
    case 'H':
1,305✔
197
      pArgs->is_binary_as_hex = true;
1,305✔
198
      break;
1,305✔
199
    case 'c':
129,374✔
200
      pArgs->cfgdir = arg;
129,374✔
201
      break;
129,374✔
202
    case 'C':
92✔
203
      pArgs->is_dump_config = true;
92✔
204
      break;
92✔
205
    case 's':
1,250,329✔
206
      pArgs->commands = arg;
1,250,329✔
207
      break;
1,250,329✔
208
    case 'r':
408✔
209
      pArgs->is_raw_time = true;
408✔
210
      break;
408✔
211
    case 'f':
143,425✔
212
      tstrncpy(pArgs->file, arg, sizeof(pArgs->file));
143,425✔
213
      break;
143,425✔
214
    case 'd':
179✔
215
      pArgs->database = arg;
179✔
216
      break;
179✔
217
    case 'k':
131✔
218
      pArgs->is_check = true;
131✔
219
      break;
131✔
220
    case 't':
92✔
221
      pArgs->is_startup = true;
92✔
222
      break;
92✔
223
    case 'w':
262✔
224
      pArgs->displayWidth = atoi(arg);
262✔
225
      break;
262✔
226
    case 'n':
57✔
227
      pArgs->netrole = arg;
57✔
228
      break;
57✔
229
    case 'l':
213✔
230
      pArgs->pktLen = atoi(arg);
213✔
231
      break;
213✔
232
    case 'N':
215✔
233
      pArgs->pktNum = atoi(arg);
215✔
234
      break;
215✔
235
#if defined(LINUX)
236
    case 'o':
207✔
237
      if (strlen(arg) >= PATH_MAX) {
207✔
238
        (void)printf("failed to set log output since length overflow, max length is %d\r\n", PATH_MAX);
×
239
        return TSDB_CODE_INVALID_CFG;
×
240
      }
241
      tsLogOutput = taosMemoryMalloc(PATH_MAX);
207✔
242
      if (!tsLogOutput) {
207✔
243
        (void)printf("failed to set log output: '%s' since %s\r\n", arg, tstrerror(terrno));
×
244
        return terrno;
×
245
      }
246
      if (taosExpandDir(arg, tsLogOutput, PATH_MAX) != 0) {
207✔
247
        (void)printf("failed to expand log output: '%s' since %s\r\n", arg, tstrerror(terrno));
×
248
        return terrno;
×
249
      }
250
      break;
207✔
251
#endif
252
    case 'E':
877✔
253
    case 'X':
254
      pArgs->dsn = arg;
877✔
255
      break;
877✔
256
    case 'T':
430✔
257
      pArgs->timeout = atoi(arg);
430✔
258
      break;
430✔
259
    case 'Z':
2,277✔
260
      pArgs->connMode = getConnMode(arg);
2,277✔
261
      break;
2,203✔
262
    case 'V':
×
263
      pArgs->is_version = true;
×
264
      break;
×
265
    case '?':
×
266
      pArgs->is_help = true;
×
267
      break;
×
268
    case 1:
×
269
      pArgs->abort = 1;
×
270
      break;
×
271
    default:
6,976,758✔
272
      return ARGP_ERR_UNKNOWN;
6,976,758✔
273
  }
274
  return 0;
1,541,435✔
275
}
276
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) || defined(_TD_DARWIN_64) || defined(TD_ASTRA)
277

278
int32_t shellParseArgsWithoutArgp(int argc, char *argv[]) {
279
  SShellArgs *pArgs = &shell.args;
280
  int32_t     ret = 0;
281

282
  for (int i = 1; i < argc; i++) {
283
    if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--usage") == 0
284
            || strcmp(argv[i], "-?") == 0 || strcmp(argv[i], "/?") == 0) {
285
      return shellParseSingleOpt('?', NULL);
286
    }
287

288
    if (strcmp(argv[i], "--binary-as-hex") == 0) {
289
      ret = shellParseSingleOpt('H', NULL);
290
      if (ret != 0) {
291
        return ret;
292
      }
293
      continue;
294
    }
295

296
    char   *key = argv[i];
297
    if (key[0] != '-') {
298
      (void)fprintf(stderr, "invalid option %s\r\n", key);
299
      return -1;
300
    }
301
    int32_t keyLen = strlen(key);
302

303
    if (key[1] == 'h' || key[1] == 'P' || key[1] == 'u' || key[1] == 'a' || key[1] == 'c' || key[1] == 's' ||
304
        key[1] == 'f' || key[1] == 'd' || key[1] == 'w' || key[1] == 'n' || key[1] == 'l' || key[1] == 'N' ||
305
        key[1] == 'E' || key[1] == 'T' || key[1] == 'X' || key[1] == 'Z') {
306
      if (keyLen > 2) {
307
        ret = shellParseSingleOpt(key[1], key + 2);
308
      } else if ((i + 1 >= argc) || (argv[i + 1][0] == '-')) {
309
        (void)fprintf(stderr, "option %s requires an argument\r\n", key);
310
        return -1;
311
      } else {
312
        ret = shellParseSingleOpt(key[1], argv[i + 1]);
313
        i++;
314
      }
315
    } else if (key[1] == 'p' || key[1] == 'q') {
316
      // -p and -q can be used with or without argument (read from stdin or command line)
317
      if (keyLen > 2) {
318
        ret = shellParseSingleOpt(key[1], key + 2);
319
      } else {
320
        ret = shellParseSingleOpt(key[1], NULL);
321
      }
322
    } else if (keyLen != 2) {
323
      (void)fprintf(stderr, "invalid option %s\r\n", key);
324
      return -1;
325
    } else if (key[1] == 'A' || key[1] == 'C' || key[1] == 'r' || key[1] == 'k' || key[1] == 't' ||
326
               key[1] == 'V' || key[1] == '?' || key[1] == 1 || key[1] == 'R'|| key[1] == 'B' || key[1] == 'H') {
327
      ret = shellParseSingleOpt(key[1], NULL);
328
    } else {
329
      (void)fprintf(stderr, "invalid option %s\r\n", key);
330
      return -1;
331
    }
332

333
    if (ret != 0) {
334
      return ret;
335
    }
336
  }
337

338
  return 0;
339
}
340
#endif
341

342
static void shellInitArgs(int argc, char *argv[]) {
1,395,910✔
343
  for (int i = 1; i < argc; i++) {
4,451,055✔
344
    if (strncmp(argv[i], "-p", 2) == 0) {
3,061,019✔
345
      // password
346
      memset(shell.args.password, 0, sizeof(shell.args.password));
3,602✔
347
      if (strlen(argv[i]) == 2) {
3,602✔
348
        (void)printf("Enter password: ");
270✔
349
        (void)taosSetConsoleEcho(false);
270✔
350
        if (scanf("%255s", shell.args.password) != 1) {
270✔
351
          (void)fprintf(stderr, "password reading error\n");
×
352
        }
353
        (void)taosSetConsoleEcho(true);
270✔
354
        if (EOF == getchar()) {
270✔
355
          (void)fprintf(stderr, "getchar() return EOF\r\n");
114✔
356
        }
357
      } else {
358
        tstrncpy(shell.args.password, (char *)(argv[i] + 2), sizeof(shell.args.password) - 1);
3,332✔
359
        strcpy(argv[i], "-p");
3,332✔
360
      }
361
      (void)printf("\r\n");
3,602✔
362
      break;
3,602✔
363
    }
364
#ifdef TD_ENTERPRISE
365
    else if (strncmp(argv[i], "-q", 2) == 0) {
3,057,417✔
366
      // token
367
      memset(shell.args.token, 0, sizeof(shell.args.token));
2,272✔
368
      if (strlen(argv[i]) == 2) {
2,272✔
369
        (void)printf("Enter token: ");
35✔
370
        (void)taosSetConsoleEcho(false);
35✔
371
        if (scanf("%255s", shell.args.token) != 1) {
35✔
372
          (void)fprintf(stderr, "token reading error\n");
×
373
        }
374
        (void)taosSetConsoleEcho(true);
35✔
375
        if (EOF == getchar()) {
35✔
376
          (void)fprintf(stderr, "getchar() return EOF\r\n");
×
377
        }
378
      } else {
379
        tstrncpy(shell.args.token, (char *)(argv[i] + 2), sizeof(shell.args.token) - 1);
2,237✔
380
        strcpy(argv[i], "-q");
2,237✔
381
      }
382
      (void)printf("\r\n");
2,272✔
383
      break;
2,272✔
384
    }
385
#endif
386
  }
387

388
  // default password
389
  if (strlen(shell.args.password) == 0) {
1,395,910✔
390
    tstrncpy(shell.args.password, TSDB_DEFAULT_PASS, sizeof(shell.args.password));
1,392,308✔
391
  }
392

393
  SShellArgs *pArgs = &shell.args;
1,395,910✔
394
  pArgs->user = TSDB_DEFAULT_USER;
1,395,910✔
395
  pArgs->pktLen = SHELL_DEF_PKG_LEN;
1,395,910✔
396
  pArgs->pktNum = SHELL_DEF_PKG_NUM;
1,395,910✔
397
  pArgs->displayWidth = SHELL_DEFAULT_MAX_BINARY_DISPLAY_WIDTH;
1,395,910✔
398
  pArgs->timeout = SHELL_WS_TIMEOUT;
1,395,910✔
399

400
  shell.exit = false;
1,395,910✔
401
}
1,395,910✔
402

403
static int32_t shellCheckArgs() {
1,395,198✔
404
  SShellArgs *pArgs = &shell.args;
1,395,198✔
405
  if (pArgs->host != NULL && (strlen(pArgs->host) <= 0 || strlen(pArgs->host) > TSDB_FQDN_LEN)) {
1,395,198✔
406
    (void)printf("Invalid host:%s\r\n", pArgs->host);
79✔
407
    return -1;
79✔
408
  }
409

410
  if (pArgs->user != NULL && (strlen(pArgs->user) <= 0 || strlen(pArgs->user) > TSDB_USER_LEN)) {
1,395,119✔
411
    (void)printf("Invalid user:%s\r\n", pArgs->user);
79✔
412
    return -1;
79✔
413
  }
414

415
  if (pArgs->auth != NULL && (strlen(pArgs->auth) <= 0 || strlen(pArgs->auth) > TSDB_PASSWORD_LEN)) {
1,395,040✔
416
    (void)printf("Invalid auth:%s\r\n", pArgs->auth);
39✔
417
    return -1;
39✔
418
  }
419

420
  if (pArgs->database != NULL && (strlen(pArgs->database) <= 0 || strlen(pArgs->database) > TSDB_DB_NAME_LEN)) {
1,395,001✔
421
    (void)printf("Invalid database:%s\r\n", pArgs->database);
×
422
    return -1;
×
423
  }
424

425
  if (pArgs->file[0] != 0) {
1,395,001✔
426
    char fullname[PATH_MAX] = {0};
143,425✔
427
    if (taosExpandDir(pArgs->file, fullname, PATH_MAX) == 0) {
143,425✔
428
      tstrncpy(pArgs->file, fullname, PATH_MAX);
143,425✔
429
    }
430
  }
431

432
  if (pArgs->cfgdir != NULL) {
1,395,001✔
433
    if (strlen(pArgs->cfgdir) <= 0 || strlen(pArgs->cfgdir) >= PATH_MAX) {
129,331✔
434
      (void)printf("Invalid cfgdir:%s\r\n", pArgs->cfgdir);
×
435
      return -1;
×
436
    } else {
437
      if (taosExpandDir(pArgs->cfgdir, configDirShell, PATH_MAX) != 0) {
129,331✔
438
        tstrncpy(configDirShell, pArgs->cfgdir, PATH_MAX);
×
439
      }
440
      // check cfg dir exist
441
      /*
442
      if(!taosIsDir(configDirShell)) {
443
        (void)printf("folder not exist. cfgdir:%s  expand:%s\r\n", pArgs->cfgdir, configDirShell);
444
        configDirShell[0] = 0;
445
        return -1;
446
      }*/
447
    }
448
  }
449

450
  if (pArgs->commands != NULL && (strlen(pArgs->commands) <= 0)) {
1,395,001✔
451
    (void)printf("Invalid commands:%s\r\n", pArgs->commands);
78✔
452
    return -1;
78✔
453
  }
454

455
  if (pArgs->netrole != NULL && !(strcmp(pArgs->netrole, "client") == 0 || strcmp(pArgs->netrole, "server") == 0)) {
1,394,923✔
456
    (void)printf("Invalid netrole:%s\r\n", pArgs->netrole);
×
457
    return -1;
×
458
  }
459

460
  if (/*pArgs->password != NULL && */ (strlen(pArgs->password) <= 0)) {
1,394,923✔
461
    (void)printf("Invalid password\r\n");
×
462
    return -1;
×
463
  }
464

465
  if (pArgs->port < 0 || pArgs->port > 65535) {
1,394,923✔
466
    (void)printf("Invalid port\r\n");
161✔
467
    return -1;
161✔
468
  }
469

470
  if (pArgs->pktLen < SHELL_MIN_PKG_LEN || pArgs->pktLen > SHELL_MAX_PKG_LEN) {
1,394,762✔
471
    (void)printf("Invalid pktLen:%d, range:[%d, %d]\r\n", pArgs->pktLen, SHELL_MIN_PKG_LEN, SHELL_MAX_PKG_LEN);
78✔
472
    return -1;
78✔
473
  }
474

475
  if (pArgs->pktNum < SHELL_MIN_PKG_NUM || pArgs->pktNum > SHELL_MAX_PKG_NUM) {
1,394,684✔
476
    (void)printf("Invalid pktNum:%d, range:[%d, %d]\r\n", pArgs->pktNum, SHELL_MIN_PKG_NUM, SHELL_MAX_PKG_NUM);
79✔
477
    return -1;
79✔
478
  }
479

480
  if (pArgs->displayWidth <= 0 || pArgs->displayWidth > 10 * 1024) {
1,394,605✔
481
    (void)printf("Invalid displayWidth:%d, range:[1, 10 * 1024]\r\n", pArgs->displayWidth);
78✔
482
    return -1;
78✔
483
  }
484

485
  return 0;
1,394,527✔
486
}
487

488
int32_t shellParseArgs(int32_t argc, char *argv[]) {
1,395,910✔
489
  shellInitArgs(argc, argv);
1,395,910✔
490
  shell.info.clientVersion =
1,395,910✔
491
      "Welcome to the %s Command Line Interface, %s Client Version:%s \r\n"
492
      "Copyright (c) 2025 by %s, all rights reserved.\r\n\r\n";
493
#ifdef CUS_NAME
494
  strcpy(shell.info.cusName, CUS_NAME);
495
#else
496
  strcpy(shell.info.cusName, "TDengine TSDB");
1,395,910✔
497
#endif
498
  char promptContinueFormat[32] = {0};
1,395,910✔
499
#ifdef CUS_PROMPT
500
  (void)snprintf(shell.info.promptHeader, sizeof(shell.info.promptHeader), "%s> ", CUS_PROMPT);
1,395,910✔
501
  (void)snprintf(promptContinueFormat, sizeof(promptContinueFormat), "%%%zus> ", strlen(CUS_PROMPT));
1,395,910✔
502
#else
503
  (void)snprintf(shell.info.promptHeader, sizeof(shell.info.promptHeader), "taos> ");
504
  (void)snprintf(promptContinueFormat, sizeof(promptContinueFormat), "%%%zus> ", strlen("taos"));
505
#endif
506
  (void)snprintf(shell.info.promptContinue, sizeof(shell.info.promptContinue), promptContinueFormat, " ");
1,395,910✔
507
  shell.info.promptSize = strlen(shell.info.promptHeader);
1,395,910✔
508
#ifdef TD_ENTERPRISE
509
  (void)snprintf(shell.info.programVersion, sizeof(shell.info.programVersion),
1,395,910✔
510
           "%s\n%s version: %s compatible_version: %s\ngit: %s\ngitOfInternal: %s\nbuild: %s", TD_PRODUCT_NAME,
511
           CUS_PROMPT, td_version, td_compatible_version, td_gitinfo, td_gitinfoOfInternal, td_buildinfo);
512
#else
513
  (void)snprintf(shell.info.programVersion, sizeof(shell.info.programVersion),
514
           "%s\n%s version: %s compatible_version: %s\ngit: %s\nbuild: %s", TD_PRODUCT_NAME, CUS_PROMPT, td_version,
515
           td_compatible_version, td_gitinfo, td_buildinfo);
516
#endif
517

518
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
519
  shell.info.osname = "Windows";
520
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "C:/TDengine/%s", SHELL_HISTORY_FILE);
521
  if (shellParseArgsWithoutArgp(argc, argv) != 0) return -1;
522
#elif defined(_TD_DARWIN_64)
523
  shell.info.osname = "Darwin";
524
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "%s/%s", getpwuid(getuid())->pw_dir, SHELL_HISTORY_FILE);
525
  if (shellParseArgsWithoutArgp(argc, argv) != 0) return -1;
526
#elif defined(TD_ASTRA)
527
  shell.info.osname = "Astra";
528
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "C:%sTDengine%s%s", TD_DIRSEP, TD_DIRSEP,
529
           SHELL_HISTORY_FILE);  // TD_ASTRA_TODO getenv("HOME")
530
  if (shellParseArgsWithoutArgp(argc, argv) != 0) return -1;
531
#else
532
  shell.info.osname = "Linux";
1,395,910✔
533
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "%s/%s", getenv("HOME"), SHELL_HISTORY_FILE);
1,395,910✔
534
  if (shellParseArgsUseArgp(argc, argv) != 0) return -1;
1,395,910✔
535
  if (shell.args.abort) {
1,395,198✔
536
    return -1;
×
537
  }
538
#endif
539

540
  return shellCheckArgs();
1,395,198✔
541
}
542

543
int32_t getDsnEnv() {
1,394,426✔
544
  if (shell.args.connMode == CONN_MODE_NATIVE) {
1,394,426✔
545
    if (shell.args.dsn != NULL) {
917✔
546
      (void)fprintf(stderr, DSN_NATIVE_CONFLICT);
37✔
547
      return -1;
37✔
548
    }
549
  } else {
550
    if (shell.args.dsn != NULL) {
1,393,509✔
551
      return 0;
840✔
552
    } else {
553
      // read cloud
554
      shell.args.dsn = getenv("TDENGINE_CLOUD_DSN");
1,392,669✔
555
      if (shell.args.dsn && strlen(shell.args.dsn) > 4) {
1,392,669✔
556
        (void)fprintf(stderr, "Use the environment variable TDENGINE_CLOUD_DSN:%s as the input for the DSN option.\r\n",
74✔
557
                shell.args.dsn);
558
        return 0;
74✔
559
      }
560

561
      // read local
562
      shell.args.dsn = getenv("TDENGINE_DSN");
1,392,595✔
563
      if (shell.args.dsn && strlen(shell.args.dsn) > 4) {
1,392,595✔
564
        (void)fprintf(stderr, "Use the environment variable TDENGINE_DSN:%s as the input for the DSN option.\r\n",
37✔
565
                shell.args.dsn);
566
        return 0;
37✔
567
      }
568
      shell.args.dsn = NULL;
1,392,558✔
569
    }
570
  }
571

572
  return 0;
1,393,438✔
573
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc