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

taosdata / TDengine / #4982

12 Mar 2026 05:32AM UTC coverage: 68.587% (+0.1%) from 68.488%
#4982

push

travis-ci

web-flow
merge: from main to 3.0 branch #34705

merge: from main to 3.0 branch

279 of 443 new or added lines in 34 files covered. (62.98%)

2352 existing lines in 132 files now uncovered.

212163 of 309332 relevant lines covered (68.59%)

135254549.82 hits per line

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

76.59
/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_VERSION  "Print program version."
43
#define SHELL_DSN      "Use dsn to connect to the cloud server or to a remote server which provides WebSocket connection."
44
#define SHELL_TIMEOUT  "Set the timeout for WebSocket query in seconds, default is 30."
45
#define SHELL_LOG_OUTPUT                                                                                              \
46
  "Specify log output. Options:\n\r\t\t\t     stdout, stderr, /dev/null, <directory>, <directory>/<filename>, "       \
47
  "<filename>\n\r\t\t\t     * If OUTPUT contains an absolute directory, logs will be stored in that directory "       \
48
  "instead of logDir.\n\r\t\t\t     * If OUTPUT contains a relative directory, logs will be stored in the directory " \
49
  "combined with logDir and the relative directory."
50

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

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

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

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

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

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

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

146
static error_t shellParseOpt(int32_t key, char *arg, struct argp_state *state) { return shellParseSingleOpt(key, arg); }
5,381,818✔
147

148
static struct argp shellArgp = {shellOptions, shellParseOpt, "", ""};
149

150
static int32_t shellParseArgsUseArgp(int argc, char *argv[]) {
875,826✔
151
  argp_program_version = shell.info.programVersion;
875,826✔
152
  error_t err = argp_parse(&shellArgp, argc, argv, 0, 0, &shell.args);
875,826✔
153
  return (err != 0);
875,124✔
154
}
155

156
#endif
157

158
#ifndef ARGP_ERR_UNKNOWN
159
#define ARGP_ERR_UNKNOWN E2BIG
160
#endif
161

162
static int32_t shellParseSingleOpt(int32_t key, char *arg) {
5,381,818✔
163
  SShellArgs *pArgs = &shell.args;
5,381,818✔
164

165
  switch (key) {
5,381,818✔
166
    case 'h':
864✔
167
      pArgs->host = arg;
864✔
168
      break;
864✔
169
    case 'P':
753✔
170
      pArgs->port = atoi(arg);
753✔
171
      if (pArgs->port == 0) {
753✔
172
        pArgs->port = -1;
159✔
173
      } else {
174
        pArgs->port_inputted = true;
594✔
175
      }
176
      break;
753✔
177
    case 'u':
3,511✔
178
      pArgs->user = arg;
3,511✔
179
      break;
3,511✔
180
    case 'p':
3,252✔
181
      break;
3,252✔
182
    case 'q':
2,160✔
183
      break;
2,160✔
184
    case 'a':
168✔
185
      pArgs->auth = arg;
168✔
186
      break;
168✔
187
    case 'A':
43✔
188
      pArgs->is_gen_auth = true;
43✔
189
      break;
43✔
190
    case 'B':
291✔
191
      pArgs->is_bi_mode = true;
291✔
192
      break;
291✔
193
    case 'c':
115,315✔
194
      pArgs->cfgdir = arg;
115,315✔
195
      break;
115,315✔
196
    case 'C':
92✔
197
      pArgs->is_dump_config = true;
92✔
198
      break;
92✔
199
    case 's':
744,813✔
200
      pArgs->commands = arg;
744,813✔
201
      break;
744,813✔
202
    case 'r':
396✔
203
      pArgs->is_raw_time = true;
396✔
204
      break;
396✔
205
    case 'f':
128,898✔
206
      tstrncpy(pArgs->file, arg, sizeof(pArgs->file));
128,898✔
207
      break;
128,898✔
208
    case 'd':
177✔
209
      pArgs->database = arg;
177✔
210
      break;
177✔
211
    case 'k':
129✔
212
      pArgs->is_check = true;
129✔
213
      break;
129✔
214
    case 't':
92✔
215
      pArgs->is_startup = true;
92✔
216
      break;
92✔
217
    case 'w':
264✔
218
      pArgs->displayWidth = atoi(arg);
264✔
219
      break;
264✔
220
    case 'n':
56✔
221
      pArgs->netrole = arg;
56✔
222
      break;
56✔
223
    case 'l':
212✔
224
      pArgs->pktLen = atoi(arg);
212✔
225
      break;
212✔
226
    case 'N':
214✔
227
      pArgs->pktNum = atoi(arg);
214✔
228
      break;
214✔
229
#if defined(LINUX)
230
    case 'o':
206✔
231
      if (strlen(arg) >= PATH_MAX) {
206✔
NEW
232
        (void)printf("failed to set log output since length overflow, max length is %d\r\n", PATH_MAX);
×
233
        return TSDB_CODE_INVALID_CFG;
×
234
      }
235
      tsLogOutput = taosMemoryMalloc(PATH_MAX);
206✔
236
      if (!tsLogOutput) {
206✔
NEW
237
        (void)printf("failed to set log output: '%s' since %s\r\n", arg, tstrerror(terrno));
×
238
        return terrno;
×
239
      }
240
      if (taosExpandDir(arg, tsLogOutput, PATH_MAX) != 0) {
206✔
NEW
241
        (void)printf("failed to expand log output: '%s' since %s\r\n", arg, tstrerror(terrno));
×
242
        return terrno;
×
243
      }
244
      break;
206✔
245
#endif
246
    case 'E':
852✔
247
    case 'X':
248
      pArgs->dsn = arg;
852✔
249
      break;
852✔
250
    case 'T':
410✔
251
      pArgs->timeout = atoi(arg);
410✔
252
      break;
410✔
253
    case 'Z':
2,272✔
254
      pArgs->connMode = getConnMode(arg);
2,272✔
255
      break;
2,198✔
256
    case 'V':
×
257
      pArgs->is_version = true;
×
258
      break;
×
259
    case '?':
×
260
      pArgs->is_help = true;
×
261
      break;
×
262
    case 1:
×
263
      pArgs->abort = 1;
×
264
      break;
×
265
    default:
4,376,378✔
266
      return ARGP_ERR_UNKNOWN;
4,376,378✔
267
  }
268
  return 0;
1,005,366✔
269
}
270
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) || defined(_TD_DARWIN_64) || defined(TD_ASTRA)
271

272
int32_t shellParseArgsWithoutArgp(int argc, char *argv[]) {
273
  SShellArgs *pArgs = &shell.args;
274
  int32_t     ret = 0;
275

276
  for (int i = 1; i < argc; i++) {
277
    if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--usage") == 0
278
            || strcmp(argv[i], "-?") == 0 || strcmp(argv[i], "/?") == 0) {
279
      return shellParseSingleOpt('?', NULL);
280
    }
281

282
    char   *key = argv[i];
283
    if (key[0] != '-') {
284
      (void)fprintf(stderr, "invalid option %s\r\n", key);
285
      return -1;
286
    }
287
    int32_t keyLen = strlen(key);
288

289
    if (key[1] == 'h' || key[1] == 'P' || key[1] == 'u' || key[1] == 'a' || key[1] == 'c' || key[1] == 's' ||
290
        key[1] == 'f' || key[1] == 'd' || key[1] == 'w' || key[1] == 'n' || key[1] == 'l' || key[1] == 'N' ||
291
        key[1] == 'E' || key[1] == 'T' || key[1] == 'X' || key[1] == 'Z') {
292
      if (keyLen > 2) {
293
        ret = shellParseSingleOpt(key[1], key + 2);
294
      } else if ((i + 1 >= argc) || (argv[i + 1][0] == '-')) {
295
        (void)fprintf(stderr, "option %s requires an argument\r\n", key);
296
        return -1;
297
      } else {
298
        ret = shellParseSingleOpt(key[1], argv[i + 1]);
299
        i++;
300
      }
301
    } else if (key[1] == 'p' || key[1] == 'q') {
302
      // -p and -q can be used with or without argument (read from stdin or command line)
303
      if (keyLen > 2) {
304
        ret = shellParseSingleOpt(key[1], key + 2);
305
      } else {
306
        ret = shellParseSingleOpt(key[1], NULL);
307
      }
308
    } else if (keyLen != 2) {
309
      (void)fprintf(stderr, "invalid option %s\r\n", key);
310
      return -1;
311
    } else if (key[1] == 'A' || key[1] == 'C' || key[1] == 'r' || key[1] == 'k' || key[1] == 't' ||
312
               key[1] == 'V' || key[1] == '?' || key[1] == 1 || key[1] == 'R'|| key[1] == 'B') {
313
      ret = shellParseSingleOpt(key[1], NULL);
314
    } else {
315
      (void)fprintf(stderr, "invalid option %s\r\n", key);
316
      return -1;
317
    }
318

319
    if (ret != 0) {
320
      return ret;
321
    }
322
  }
323

324
  return 0;
325
}
326
#endif
327

328
static void shellInitArgs(int argc, char *argv[]) {
875,826✔
329
  for (int i = 1; i < argc; i++) {
2,861,580✔
330
    if (strncmp(argv[i], "-p", 2) == 0) {
1,991,310✔
331
      // password
332
      memset(shell.args.password, 0, sizeof(shell.args.password));
3,396✔
333
      if (strlen(argv[i]) == 2) {
3,396✔
334
        (void)printf("Enter password: ");
257✔
335
        (void)taosSetConsoleEcho(false);
257✔
336
        if (scanf("%255s", shell.args.password) != 1) {
257✔
NEW
337
          (void)fprintf(stderr, "password reading error\n");
×
338
        }
339
        (void)taosSetConsoleEcho(true);
257✔
340
        if (EOF == getchar()) {
257✔
341
          (void)fprintf(stderr, "getchar() return EOF\r\n");
113✔
342
        }
343
      } else {
344
        tstrncpy(shell.args.password, (char *)(argv[i] + 2), sizeof(shell.args.password) - 1);
3,139✔
345
        strcpy(argv[i], "-p");
3,139✔
346
      }
347
      (void)printf("\r\n");
3,396✔
348
      break;
3,396✔
349
    }
350
#ifdef TD_ENTERPRISE
351
    else if (strncmp(argv[i], "-q", 2) == 0) {
1,987,914✔
352
      // token
353
      memset(shell.args.token, 0, sizeof(shell.args.token));
2,160✔
354
      if (strlen(argv[i]) == 2) {
2,160✔
355
        (void)printf("Enter token: ");
35✔
356
        (void)taosSetConsoleEcho(false);
35✔
357
        if (scanf("%255s", shell.args.token) != 1) {
35✔
NEW
358
          (void)fprintf(stderr, "token reading error\n");
×
359
        }
360
        (void)taosSetConsoleEcho(true);
35✔
361
        if (EOF == getchar()) {
35✔
NEW
362
          (void)fprintf(stderr, "getchar() return EOF\r\n");
×
363
        }
364
      } else {
365
        tstrncpy(shell.args.token, (char *)(argv[i] + 2), sizeof(shell.args.token) - 1);
2,125✔
366
        strcpy(argv[i], "-q");
2,125✔
367
      }
368
      (void)printf("\r\n");
2,160✔
369
      break;
2,160✔
370
    }
371
#endif
372
  }
373

374
  // default password
375
  if (strlen(shell.args.password) == 0) {
875,826✔
376
    tstrncpy(shell.args.password, TSDB_DEFAULT_PASS, sizeof(shell.args.password));
872,430✔
377
  }
378

379
  SShellArgs *pArgs = &shell.args;
875,826✔
380
  pArgs->user = TSDB_DEFAULT_USER;
875,826✔
381
  pArgs->pktLen = SHELL_DEF_PKG_LEN;
875,826✔
382
  pArgs->pktNum = SHELL_DEF_PKG_NUM;
875,826✔
383
  pArgs->displayWidth = SHELL_DEFAULT_MAX_BINARY_DISPLAY_WIDTH;
875,826✔
384
  pArgs->timeout = SHELL_WS_TIMEOUT;
875,826✔
385

386
  shell.exit = false;
875,826✔
387
}
875,826✔
388

389
static int32_t shellCheckArgs() {
875,124✔
390
  SShellArgs *pArgs = &shell.args;
875,124✔
391
  if (pArgs->host != NULL && (strlen(pArgs->host) <= 0 || strlen(pArgs->host) > TSDB_FQDN_LEN)) {
875,124✔
392
    (void)printf("Invalid host:%s\r\n", pArgs->host);
80✔
393
    return -1;
80✔
394
  }
395

396
  if (pArgs->user != NULL && (strlen(pArgs->user) <= 0 || strlen(pArgs->user) > TSDB_USER_LEN)) {
875,044✔
397
    (void)printf("Invalid user:%s\r\n", pArgs->user);
80✔
398
    return -1;
80✔
399
  }
400

401
  if (pArgs->auth != NULL && (strlen(pArgs->auth) <= 0 || strlen(pArgs->auth) > TSDB_PASSWORD_LEN)) {
874,964✔
402
    (void)printf("Invalid auth:%s\r\n", pArgs->auth);
38✔
403
    return -1;
38✔
404
  }
405

406
  if (pArgs->database != NULL && (strlen(pArgs->database) <= 0 || strlen(pArgs->database) > TSDB_DB_NAME_LEN)) {
874,926✔
NEW
407
    (void)printf("Invalid database:%s\r\n", pArgs->database);
×
408
    return -1;
×
409
  }
410

411
  if (pArgs->file[0] != 0) {
874,926✔
412
    char fullname[PATH_MAX] = {0};
128,898✔
413
    if (taosExpandDir(pArgs->file, fullname, PATH_MAX) == 0) {
128,898✔
414
      tstrncpy(pArgs->file, fullname, PATH_MAX);
128,898✔
415
    }
416
  }
417

418
  if (pArgs->cfgdir != NULL) {
874,926✔
419
    if (strlen(pArgs->cfgdir) <= 0 || strlen(pArgs->cfgdir) >= PATH_MAX) {
115,273✔
NEW
420
      (void)printf("Invalid cfgdir:%s\r\n", pArgs->cfgdir);
×
421
      return -1;
×
422
    } else {
423
      if (taosExpandDir(pArgs->cfgdir, configDirShell, PATH_MAX) != 0) {
115,273✔
424
        tstrncpy(configDirShell, pArgs->cfgdir, PATH_MAX);
×
425
      }
426
      // check cfg dir exist
427
      /*
428
      if(!taosIsDir(configDirShell)) {
429
        (void)printf("folder not exist. cfgdir:%s  expand:%s\r\n", pArgs->cfgdir, configDirShell);
430
        configDirShell[0] = 0;
431
        return -1;
432
      }*/
433
    }
434
  }
435

436
  if (pArgs->commands != NULL && (strlen(pArgs->commands) <= 0)) {
874,926✔
437
    (void)printf("Invalid commands:%s\r\n", pArgs->commands);
78✔
438
    return -1;
78✔
439
  }
440

441
  if (pArgs->netrole != NULL && !(strcmp(pArgs->netrole, "client") == 0 || strcmp(pArgs->netrole, "server") == 0)) {
874,848✔
NEW
442
    (void)printf("Invalid netrole:%s\r\n", pArgs->netrole);
×
443
    return -1;
×
444
  }
445

446
  if (/*pArgs->password != NULL && */ (strlen(pArgs->password) <= 0)) {
874,848✔
NEW
447
    (void)printf("Invalid password\r\n");
×
448
    return -1;
×
449
  }
450

451
  if (pArgs->port < 0 || pArgs->port > 65535) {
874,848✔
452
    (void)printf("Invalid port\r\n");
159✔
453
    return -1;
159✔
454
  }
455

456
  if (pArgs->pktLen < SHELL_MIN_PKG_LEN || pArgs->pktLen > SHELL_MAX_PKG_LEN) {
874,689✔
457
    (void)printf("Invalid pktLen:%d, range:[%d, %d]\r\n", pArgs->pktLen, SHELL_MIN_PKG_LEN, SHELL_MAX_PKG_LEN);
78✔
458
    return -1;
78✔
459
  }
460

461
  if (pArgs->pktNum < SHELL_MIN_PKG_NUM || pArgs->pktNum > SHELL_MAX_PKG_NUM) {
874,611✔
462
    (void)printf("Invalid pktNum:%d, range:[%d, %d]\r\n", pArgs->pktNum, SHELL_MIN_PKG_NUM, SHELL_MAX_PKG_NUM);
79✔
463
    return -1;
79✔
464
  }
465

466
  if (pArgs->displayWidth <= 0 || pArgs->displayWidth > 10 * 1024) {
874,532✔
467
    (void)printf("Invalid displayWidth:%d, range:[1, 10 * 1024]\r\n", pArgs->displayWidth);
79✔
468
    return -1;
79✔
469
  }
470

471
  return 0;
874,453✔
472
}
473

474
int32_t shellParseArgs(int32_t argc, char *argv[]) {
875,826✔
475
  shellInitArgs(argc, argv);
875,826✔
476
  shell.info.clientVersion =
875,826✔
477
      "Welcome to the %s Command Line Interface, %s Client Version:%s \r\n"
478
      "Copyright (c) 2025 by %s, all rights reserved.\r\n\r\n";
479
#ifdef CUS_NAME
480
  strcpy(shell.info.cusName, CUS_NAME);
481
#else
482
  strcpy(shell.info.cusName, "TDengine TSDB");
875,826✔
483
#endif
484
  char promptContinueFormat[32] = {0};
875,826✔
485
#ifdef CUS_PROMPT
486
  (void)snprintf(shell.info.promptHeader, sizeof(shell.info.promptHeader), "%s> ", CUS_PROMPT);
875,826✔
487
  (void)snprintf(promptContinueFormat, sizeof(promptContinueFormat), "%%%zus> ", strlen(CUS_PROMPT));
875,826✔
488
#else
489
  (void)snprintf(shell.info.promptHeader, sizeof(shell.info.promptHeader), "taos> ");
490
  (void)snprintf(promptContinueFormat, sizeof(promptContinueFormat), "%%%zus> ", strlen("taos"));
491
#endif
492
  (void)snprintf(shell.info.promptContinue, sizeof(shell.info.promptContinue), promptContinueFormat, " ");
875,826✔
493
  shell.info.promptSize = strlen(shell.info.promptHeader);
875,826✔
494
#ifdef TD_ENTERPRISE
495
  (void)snprintf(shell.info.programVersion, sizeof(shell.info.programVersion),
875,826✔
496
           "%s\n%s version: %s compatible_version: %s\ngit: %s\ngitOfInternal: %s\nbuild: %s", TD_PRODUCT_NAME,
497
           CUS_PROMPT, td_version, td_compatible_version, td_gitinfo, td_gitinfoOfInternal, td_buildinfo);
498
#else
499
  (void)snprintf(shell.info.programVersion, sizeof(shell.info.programVersion),
500
           "%s\n%s version: %s compatible_version: %s\ngit: %s\nbuild: %s", TD_PRODUCT_NAME, CUS_PROMPT, td_version,
501
           td_compatible_version, td_gitinfo, td_buildinfo);
502
#endif
503

504
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
505
  shell.info.osname = "Windows";
506
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "C:/TDengine/%s", SHELL_HISTORY_FILE);
507
  if (shellParseArgsWithoutArgp(argc, argv) != 0) return -1;
508
#elif defined(_TD_DARWIN_64)
509
  shell.info.osname = "Darwin";
510
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "%s/%s", getpwuid(getuid())->pw_dir, SHELL_HISTORY_FILE);
511
  if (shellParseArgsWithoutArgp(argc, argv) != 0) return -1;
512
#elif defined(TD_ASTRA)
513
  shell.info.osname = "Astra";
514
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "C:%sTDengine%s%s", TD_DIRSEP, TD_DIRSEP,
515
           SHELL_HISTORY_FILE);  // TD_ASTRA_TODO getenv("HOME")
516
  if (shellParseArgsWithoutArgp(argc, argv) != 0) return -1;
517
#else
518
  shell.info.osname = "Linux";
875,826✔
519
  (void)snprintf(shell.history.file, TSDB_FILENAME_LEN, "%s/%s", getenv("HOME"), SHELL_HISTORY_FILE);
875,826✔
520
  if (shellParseArgsUseArgp(argc, argv) != 0) return -1;
875,826✔
521
  if (shell.args.abort) {
875,124✔
522
    return -1;
×
523
  }
524
#endif
525

526
  return shellCheckArgs();
875,124✔
527
}
528

529
int32_t getDsnEnv() {
874,354✔
530
  if (shell.args.connMode == CONN_MODE_NATIVE) {
874,354✔
531
    if (shell.args.dsn != NULL) {
918✔
532
      (void)fprintf(stderr, DSN_NATIVE_CONFLICT);
37✔
533
      return -1;
37✔
534
    }
535
  } else {
536
    if (shell.args.dsn != NULL) {
873,436✔
537
      return 0;
815✔
538
    } else {
539
      // read cloud
540
      shell.args.dsn = getenv("TDENGINE_CLOUD_DSN");
872,621✔
541
      if (shell.args.dsn && strlen(shell.args.dsn) > 4) {
872,621✔
542
        (void)fprintf(stderr, "Use the environment variable TDENGINE_CLOUD_DSN:%s as the input for the DSN option.\r\n",
74✔
543
                shell.args.dsn);
544
        return 0;
74✔
545
      }
546

547
      // read local
548
      shell.args.dsn = getenv("TDENGINE_DSN");
872,547✔
549
      if (shell.args.dsn && strlen(shell.args.dsn) > 4) {
872,547✔
550
        (void)fprintf(stderr, "Use the environment variable TDENGINE_DSN:%s as the input for the DSN option.\r\n",
37✔
551
                shell.args.dsn);
552
        return 0;
37✔
553
      }
554
      shell.args.dsn = NULL;
872,510✔
555
    }
556
  }
557

558
  return 0;
873,391✔
559
}
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