Coverage Report

Created: 2025-08-26 07:08

/src/PROJ/curl/lib/curl_trc.c
Line
Count
Source (jump to first uncovered line)
1
/***************************************************************************
2
 *                                  _   _ ____  _
3
 *  Project                     ___| | | |  _ \| |
4
 *                             / __| | | | |_) | |
5
 *                            | (__| |_| |  _ <| |___
6
 *                             \___|\___/|_| \_\_____|
7
 *
8
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9
 *
10
 * This software is licensed as described in the file COPYING, which
11
 * you should have received as part of this distribution. The terms
12
 * are also available at https://curl.se/docs/copyright.html.
13
 *
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 * copies of the Software, and permit persons to whom the Software is
16
 * furnished to do so, under the terms of the COPYING file.
17
 *
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 * KIND, either express or implied.
20
 *
21
 * SPDX-License-Identifier: curl
22
 *
23
 ***************************************************************************/
24
25
#include "curl_setup.h"
26
27
#include <curl/curl.h>
28
29
#include "curl_trc.h"
30
#include "urldata.h"
31
#include "easyif.h"
32
#include "cfilters.h"
33
#include "multiif.h"
34
35
#include "cf-socket.h"
36
#include "connect.h"
37
#include "doh.h"
38
#include "http2.h"
39
#include "http_proxy.h"
40
#include "cf-h1-proxy.h"
41
#include "cf-h2-proxy.h"
42
#include "cf-haproxy.h"
43
#include "cf-https-connect.h"
44
#include "cf-ip-happy.h"
45
#include "socks.h"
46
#include "curlx/strparse.h"
47
#include "vtls/vtls.h"
48
#include "vquic/vquic.h"
49
50
/* The last 3 #include files should be in this order */
51
#include "curl_printf.h"
52
#include "curl_memory.h"
53
#include "memdebug.h"
54
55
static void trc_write(struct Curl_easy *data, curl_infotype type,
56
                      const char *ptr, size_t size)
57
0
{
58
0
  if(data->set.verbose) {
59
0
    if(data->set.fdebug) {
60
0
      bool inCallback = Curl_is_in_callback(data);
61
0
      Curl_set_in_callback(data, TRUE);
62
0
      (void)(*data->set.fdebug)(data, type, CURL_UNCONST(ptr), size,
63
0
                                data->set.debugdata);
64
0
      Curl_set_in_callback(data, inCallback);
65
0
    }
66
0
    else {
67
0
      static const char s_infotype[CURLINFO_END][3] = {
68
0
        "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
69
0
      switch(type) {
70
0
      case CURLINFO_TEXT:
71
0
      case CURLINFO_HEADER_OUT:
72
0
      case CURLINFO_HEADER_IN:
73
0
        fwrite(s_infotype[type], 2, 1, data->set.err);
74
0
        fwrite(ptr, size, 1, data->set.err);
75
0
        break;
76
0
      default: /* nada */
77
0
        break;
78
0
      }
79
0
    }
80
0
  }
81
0
}
82
83
/* max length we trace before ending in '...' */
84
0
#define TRC_LINE_MAX 2048
85
86
0
#define CURL_TRC_FMT_IDSC   "[x-%" CURL_FORMAT_CURL_OFF_T "] "
87
0
#define CURL_TRC_FMT_IDSD   "[%" CURL_FORMAT_CURL_OFF_T "-x] "
88
0
#define CURL_TRC_FMT_IDSDC  "[%" CURL_FORMAT_CURL_OFF_T "-%" \
89
0
                            CURL_FORMAT_CURL_OFF_T "] "
90
91
static struct curl_trc_feat Curl_trc_feat_ids = {
92
  "LIB-IDS",
93
  CURL_LOG_LVL_NONE,
94
};
95
#define CURL_TRC_IDS(data) \
96
0
             (Curl_trc_is_verbose(data) && \
97
0
             Curl_trc_feat_ids.log_level >= CURL_LOG_LVL_INFO)
98
99
static size_t trc_print_ids(struct Curl_easy *data, char *buf, size_t maxlen)
100
0
{
101
0
  curl_off_t cid = data->conn ?
102
0
                   data->conn->connection_id : data->state.recent_conn_id;
103
0
  if(data->id >= 0) {
104
0
    if(cid >= 0)
105
0
      return msnprintf(buf, maxlen, CURL_TRC_FMT_IDSDC, data->id, cid);
106
0
    else
107
0
      return msnprintf(buf, maxlen, CURL_TRC_FMT_IDSD, data->id);
108
0
  }
109
0
  else if(cid >= 0)
110
0
    return msnprintf(buf, maxlen, CURL_TRC_FMT_IDSC, cid);
111
0
  else {
112
0
    return msnprintf(buf, maxlen, "[x-x] ");
113
0
  }
114
0
}
115
116
static size_t trc_end_buf(char *buf, size_t len, size_t maxlen, bool addnl)
117
0
{
118
  /* make sure we end the trace line in `buf` properly. It needs
119
   * to end with a terminating '\0' or '\n\0' */
120
0
  if(len >= (maxlen - (addnl ? 2 : 1))) {
121
0
    len = maxlen - 5;
122
0
    buf[len++] = '.';
123
0
    buf[len++] = '.';
124
0
    buf[len++] = '.';
125
0
    buf[len++] = '\n';
126
0
  }
127
0
  else if(addnl)
128
0
    buf[len++] = '\n';
129
0
  buf[len] = '\0';
130
0
  return len;
131
0
}
132
133
void Curl_debug(struct Curl_easy *data, curl_infotype type,
134
                const char *ptr, size_t size)
135
0
{
136
0
  if(data->set.verbose) {
137
0
    static const char s_infotype[CURLINFO_END][3] = {
138
0
      "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
139
0
    char buf[TRC_LINE_MAX];
140
0
    size_t len;
141
0
    if(data->set.fdebug) {
142
0
      bool inCallback = Curl_is_in_callback(data);
143
144
0
      if(CURL_TRC_IDS(data) && (size < TRC_LINE_MAX)) {
145
0
        len = trc_print_ids(data, buf, TRC_LINE_MAX);
146
0
        len += msnprintf(buf + len, TRC_LINE_MAX - len, "%.*s",
147
0
                         (int)size, ptr);
148
0
        len = trc_end_buf(buf, len, TRC_LINE_MAX, FALSE);
149
0
        Curl_set_in_callback(data, TRUE);
150
0
        (void)(*data->set.fdebug)(data, type, buf, len, data->set.debugdata);
151
0
        Curl_set_in_callback(data, inCallback);
152
0
      }
153
0
      else {
154
0
        Curl_set_in_callback(data, TRUE);
155
0
        (void)(*data->set.fdebug)(data, type, CURL_UNCONST(ptr),
156
0
                                  size, data->set.debugdata);
157
0
        Curl_set_in_callback(data, inCallback);
158
0
      }
159
0
    }
160
0
    else {
161
0
      switch(type) {
162
0
      case CURLINFO_TEXT:
163
0
      case CURLINFO_HEADER_OUT:
164
0
      case CURLINFO_HEADER_IN:
165
0
#ifndef CURL_DISABLE_VERBOSE_STRINGS
166
0
        if(CURL_TRC_IDS(data)) {
167
0
          len = trc_print_ids(data, buf, TRC_LINE_MAX);
168
0
          fwrite(buf, len, 1, data->set.err);
169
0
        }
170
0
#endif
171
0
        fwrite(s_infotype[type], 2, 1, data->set.err);
172
0
        fwrite(ptr, size, 1, data->set.err);
173
0
        break;
174
0
      default: /* nada */
175
0
        break;
176
0
      }
177
0
    }
178
0
  }
179
0
}
180
181
/* Curl_failf() is for messages stating why we failed.
182
 * The message SHALL NOT include any LF or CR.
183
 */
184
void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
185
0
{
186
0
  DEBUGASSERT(!strchr(fmt, '\n'));
187
0
  if(data->set.verbose || data->set.errorbuffer) {
188
0
    va_list ap;
189
0
    size_t len;
190
0
    char error[CURL_ERROR_SIZE + 2];
191
0
    va_start(ap, fmt);
192
0
    len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
193
194
0
    if(data->set.errorbuffer && !data->state.errorbuf) {
195
0
      strcpy(data->set.errorbuffer, error);
196
0
      data->state.errorbuf = TRUE; /* wrote error string */
197
0
    }
198
0
    error[len++] = '\n';
199
0
    error[len] = '\0';
200
0
    trc_write(data, CURLINFO_TEXT, error, len);
201
0
    va_end(ap);
202
0
  }
203
0
}
204
205
#ifndef CURL_DISABLE_VERBOSE_STRINGS
206
207
static void trc_infof(struct Curl_easy *data,
208
                      struct curl_trc_feat *feat,
209
                      const char *opt_id, int opt_id_idx,
210
                      const char * const fmt, va_list ap) CURL_PRINTF(5, 0);
211
212
static void trc_infof(struct Curl_easy *data,
213
                      struct curl_trc_feat *feat,
214
                      const char *opt_id, int opt_id_idx,
215
                      const char * const fmt, va_list ap)
216
0
{
217
0
  size_t len = 0;
218
0
  char buf[TRC_LINE_MAX];
219
220
0
  if(CURL_TRC_IDS(data))
221
0
    len += trc_print_ids(data, buf + len, TRC_LINE_MAX - len);
222
0
  if(feat)
223
0
    len += msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", feat->name);
224
0
  if(opt_id) {
225
0
    if(opt_id_idx > 0)
226
0
      len += msnprintf(buf + len, TRC_LINE_MAX - len, "[%s-%d] ",
227
0
                       opt_id, opt_id_idx);
228
0
    else
229
0
      len += msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", opt_id);
230
0
  }
231
0
  len += mvsnprintf(buf + len, TRC_LINE_MAX - len, fmt, ap);
232
0
  len = trc_end_buf(buf, len, TRC_LINE_MAX, TRUE);
233
0
  trc_write(data, CURLINFO_TEXT, buf, len);
234
0
}
235
236
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
237
0
{
238
0
  DEBUGASSERT(!strchr(fmt, '\n'));
239
0
  if(Curl_trc_is_verbose(data)) {
240
0
    va_list ap;
241
0
    va_start(ap, fmt);
242
0
    trc_infof(data, data->state.feat, NULL, 0, fmt, ap);
243
0
    va_end(ap);
244
0
  }
245
0
}
246
247
void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf,
248
                       const char *fmt, ...)
249
0
{
250
0
  DEBUGASSERT(cf);
251
0
  if(Curl_trc_cf_is_verbose(cf, data)) {
252
0
    va_list ap;
253
0
    va_start(ap, fmt);
254
0
    trc_infof(data, data->state.feat, cf->cft->name, cf->sockindex, fmt, ap);
255
0
    va_end(ap);
256
0
  }
257
0
}
258
259
struct curl_trc_feat Curl_trc_feat_multi = {
260
  "MULTI",
261
  CURL_LOG_LVL_NONE,
262
};
263
struct curl_trc_feat Curl_trc_feat_read = {
264
  "READ",
265
  CURL_LOG_LVL_NONE,
266
};
267
struct curl_trc_feat Curl_trc_feat_write = {
268
  "WRITE",
269
  CURL_LOG_LVL_NONE,
270
};
271
struct curl_trc_feat Curl_trc_feat_dns = {
272
  "DNS",
273
  CURL_LOG_LVL_NONE,
274
};
275
276
277
static const char * const Curl_trc_mstate_names[]={
278
  "INIT",
279
  "PENDING",
280
  "SETUP",
281
  "CONNECT",
282
  "RESOLVING",
283
  "CONNECTING",
284
  "TUNNELING",
285
  "PROTOCONNECT",
286
  "PROTOCONNECTING",
287
  "DO",
288
  "DOING",
289
  "DOING_MORE",
290
  "DID",
291
  "PERFORMING",
292
  "RATELIMITING",
293
  "DONE",
294
  "COMPLETED",
295
  "MSGSENT",
296
};
297
298
const char *Curl_trc_mstate_name(int state)
299
0
{
300
0
  if((state >= 0) && ((size_t)state < CURL_ARRAYSIZE(Curl_trc_mstate_names)))
301
0
    return Curl_trc_mstate_names[(size_t)state];
302
0
  return "?";
303
0
}
304
305
void Curl_trc_multi(struct Curl_easy *data, const char *fmt, ...)
306
0
{
307
0
  DEBUGASSERT(!strchr(fmt, '\n'));
308
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_multi)) {
309
0
    const char *sname = (data->id >= 0) ?
310
0
                        Curl_trc_mstate_name(data->mstate) : NULL;
311
0
    va_list ap;
312
0
    va_start(ap, fmt);
313
0
    trc_infof(data, &Curl_trc_feat_multi, sname, 0, fmt, ap);
314
0
    va_end(ap);
315
0
  }
316
0
}
317
318
void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
319
0
{
320
0
  DEBUGASSERT(!strchr(fmt, '\n'));
321
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) {
322
0
    va_list ap;
323
0
    va_start(ap, fmt);
324
0
    trc_infof(data, &Curl_trc_feat_read, NULL, 0, fmt, ap);
325
0
    va_end(ap);
326
0
  }
327
0
}
328
329
void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
330
0
{
331
0
  DEBUGASSERT(!strchr(fmt, '\n'));
332
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_write)) {
333
0
    va_list ap;
334
0
    va_start(ap, fmt);
335
0
    trc_infof(data, &Curl_trc_feat_write, NULL, 0, fmt, ap);
336
0
    va_end(ap);
337
0
  }
338
0
}
339
340
void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...)
341
0
{
342
0
  DEBUGASSERT(!strchr(fmt, '\n'));
343
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) {
344
0
    va_list ap;
345
0
    va_start(ap, fmt);
346
0
    trc_infof(data, &Curl_trc_feat_dns, NULL, 0, fmt, ap);
347
0
    va_end(ap);
348
0
  }
349
0
}
350
351
#ifndef CURL_DISABLE_FTP
352
struct curl_trc_feat Curl_trc_feat_ftp = {
353
  "FTP",
354
  CURL_LOG_LVL_NONE,
355
};
356
357
void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
358
0
{
359
0
  DEBUGASSERT(!strchr(fmt, '\n'));
360
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ftp)) {
361
0
    va_list ap;
362
0
    va_start(ap, fmt);
363
0
    trc_infof(data, &Curl_trc_feat_ftp, NULL, 0, fmt, ap);
364
0
    va_end(ap);
365
0
  }
366
0
}
367
#endif /* !CURL_DISABLE_FTP */
368
369
#ifndef CURL_DISABLE_SMTP
370
struct curl_trc_feat Curl_trc_feat_smtp = {
371
  "SMTP",
372
  CURL_LOG_LVL_NONE,
373
};
374
375
void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
376
0
{
377
0
  DEBUGASSERT(!strchr(fmt, '\n'));
378
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) {
379
0
    va_list ap;
380
0
    va_start(ap, fmt);
381
0
    trc_infof(data, &Curl_trc_feat_smtp, NULL, 0, fmt, ap);
382
0
    va_end(ap);
383
0
  }
384
0
}
385
#endif /* !CURL_DISABLE_SMTP */
386
387
#ifdef USE_SSL
388
struct curl_trc_feat Curl_trc_feat_ssls = {
389
  "SSLS",
390
  CURL_LOG_LVL_NONE,
391
};
392
393
void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...)
394
0
{
395
0
  DEBUGASSERT(!strchr(fmt, '\n'));
396
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssls)) {
397
0
    va_list ap;
398
0
    va_start(ap, fmt);
399
0
    trc_infof(data, &Curl_trc_feat_ssls, NULL, 0, fmt, ap);
400
0
    va_end(ap);
401
0
  }
402
0
}
403
#endif /* USE_SSL */
404
405
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
406
struct curl_trc_feat Curl_trc_feat_ws = {
407
  "WS",
408
  CURL_LOG_LVL_NONE,
409
};
410
411
void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
412
0
{
413
0
  DEBUGASSERT(!strchr(fmt, '\n'));
414
0
  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) {
415
0
    va_list ap;
416
0
    va_start(ap, fmt);
417
0
    trc_infof(data, &Curl_trc_feat_ws, NULL, 0, fmt, ap);
418
0
    va_end(ap);
419
0
  }
420
0
}
421
#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */
422
423
0
#define TRC_CT_NONE        (0)
424
0
#define TRC_CT_PROTOCOL    (1<<(0))
425
0
#define TRC_CT_NETWORK     (1<<(1))
426
0
#define TRC_CT_PROXY       (1<<(2))
427
#define TRC_CT_INTERNALS   (1<<(3))
428
429
struct trc_feat_def {
430
  struct curl_trc_feat *feat;
431
  unsigned int category;
432
};
433
434
static struct trc_feat_def trc_feats[] = {
435
  { &Curl_trc_feat_ids,       TRC_CT_INTERNALS },
436
  { &Curl_trc_feat_multi,     TRC_CT_NETWORK },
437
  { &Curl_trc_feat_read,      TRC_CT_NONE },
438
  { &Curl_trc_feat_write,     TRC_CT_NONE },
439
  { &Curl_trc_feat_dns,       TRC_CT_NETWORK },
440
#ifndef CURL_DISABLE_FTP
441
  { &Curl_trc_feat_ftp,       TRC_CT_PROTOCOL },
442
#endif
443
#ifndef CURL_DISABLE_DOH
444
#endif
445
#ifndef CURL_DISABLE_SMTP
446
  { &Curl_trc_feat_smtp,      TRC_CT_PROTOCOL },
447
#endif
448
#ifdef USE_SSL
449
  { &Curl_trc_feat_ssls,      TRC_CT_NETWORK },
450
#endif
451
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
452
  { &Curl_trc_feat_ws,        TRC_CT_PROTOCOL },
453
#endif
454
};
455
456
struct trc_cft_def {
457
  struct Curl_cftype *cft;
458
  unsigned int category;
459
};
460
461
static struct trc_cft_def trc_cfts[] = {
462
  { &Curl_cft_tcp,            TRC_CT_NETWORK },
463
  { &Curl_cft_udp,            TRC_CT_NETWORK },
464
  { &Curl_cft_unix,           TRC_CT_NETWORK },
465
  { &Curl_cft_tcp_accept,     TRC_CT_NETWORK },
466
  { &Curl_cft_ip_happy,       TRC_CT_NETWORK },
467
  { &Curl_cft_setup,          TRC_CT_PROTOCOL },
468
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2)
469
  { &Curl_cft_nghttp2,        TRC_CT_PROTOCOL },
470
#endif
471
#ifdef USE_SSL
472
  { &Curl_cft_ssl,            TRC_CT_NETWORK },
473
#ifndef CURL_DISABLE_PROXY
474
  { &Curl_cft_ssl_proxy,      TRC_CT_PROXY },
475
#endif
476
#endif
477
#ifndef CURL_DISABLE_PROXY
478
#ifndef CURL_DISABLE_HTTP
479
  { &Curl_cft_h1_proxy,       TRC_CT_PROXY },
480
#ifdef USE_NGHTTP2
481
  { &Curl_cft_h2_proxy,       TRC_CT_PROXY },
482
#endif
483
  { &Curl_cft_http_proxy,     TRC_CT_PROXY },
484
#endif /* !CURL_DISABLE_HTTP */
485
  { &Curl_cft_haproxy,        TRC_CT_PROXY },
486
  { &Curl_cft_socks_proxy,    TRC_CT_PROXY },
487
#endif /* !CURL_DISABLE_PROXY */
488
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3)
489
  { &Curl_cft_http3,          TRC_CT_PROTOCOL },
490
#endif
491
#ifndef CURL_DISABLE_HTTP
492
  { &Curl_cft_http_connect,   TRC_CT_PROTOCOL },
493
#endif
494
};
495
496
static void trc_apply_level_by_name(struct Curl_str *token, int lvl)
497
0
{
498
0
  size_t i;
499
500
0
  for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) {
501
0
    if(curlx_str_casecompare(token, trc_cfts[i].cft->name)) {
502
0
      trc_cfts[i].cft->log_level = lvl;
503
0
      break;
504
0
    }
505
0
  }
506
0
  for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) {
507
0
    if(curlx_str_casecompare(token, trc_feats[i].feat->name)) {
508
0
      trc_feats[i].feat->log_level = lvl;
509
0
      break;
510
0
    }
511
0
  }
512
0
}
513
514
static void trc_apply_level_by_category(int category, int lvl)
515
0
{
516
0
  size_t i;
517
518
0
  for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) {
519
0
    if(!category || (trc_cfts[i].category & category))
520
0
      trc_cfts[i].cft->log_level = lvl;
521
0
  }
522
0
  for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) {
523
0
    if(!category || (trc_feats[i].category & category))
524
0
      trc_feats[i].feat->log_level = lvl;
525
0
  }
526
0
}
527
528
static CURLcode trc_opt(const char *config)
529
0
{
530
0
  struct Curl_str out;
531
0
  while(!curlx_str_until(&config, &out, 32, ',')) {
532
0
    int lvl = CURL_LOG_LVL_INFO;
533
0
    const char *token = curlx_str(&out);
534
535
0
    if(*token == '-') {
536
0
      lvl = CURL_LOG_LVL_NONE;
537
0
      curlx_str_nudge(&out, 1);
538
0
    }
539
0
    else if(*token == '+')
540
0
      curlx_str_nudge(&out, 1);
541
542
0
    if(curlx_str_casecompare(&out, "all"))
543
0
      trc_apply_level_by_category(TRC_CT_NONE, lvl);
544
0
    else if(curlx_str_casecompare(&out, "protocol"))
545
0
      trc_apply_level_by_category(TRC_CT_PROTOCOL, lvl);
546
0
    else if(curlx_str_casecompare(&out, "network"))
547
0
      trc_apply_level_by_category(TRC_CT_NETWORK, lvl);
548
0
    else if(curlx_str_casecompare(&out, "proxy"))
549
0
      trc_apply_level_by_category(TRC_CT_PROXY, lvl);
550
0
    else if(curlx_str_casecompare(&out, "doh")) {
551
0
      struct Curl_str dns = { "dns", 3 };
552
0
      trc_apply_level_by_name(&dns, lvl);
553
0
    }
554
0
    else
555
0
      trc_apply_level_by_name(&out, lvl);
556
557
0
    if(curlx_str_single(&config, ','))
558
0
      break;
559
0
  }
560
0
  return CURLE_OK;
561
0
}
562
563
CURLcode Curl_trc_opt(const char *config)
564
0
{
565
0
  CURLcode result = config ? trc_opt(config) : CURLE_OK;
566
#ifdef DEBUGBUILD
567
  /* CURL_DEBUG can override anything */
568
  if(!result) {
569
    const char *dbg_config = getenv("CURL_DEBUG");
570
    if(dbg_config)
571
      result = trc_opt(dbg_config);
572
  }
573
#endif /* DEBUGBUILD */
574
0
  return result;
575
0
}
576
577
CURLcode Curl_trc_init(void)
578
0
{
579
#ifdef DEBUGBUILD
580
  return Curl_trc_opt(NULL);
581
#else
582
0
  return CURLE_OK;
583
0
#endif
584
0
}
585
586
#else /* CURL_DISABLE_VERBOSE_STRINGS */
587
588
CURLcode Curl_trc_init(void)
589
{
590
  return CURLE_OK;
591
}
592
593
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
594
{
595
  (void)data; (void)fmt;
596
}
597
598
void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf,
599
                       const char *fmt, ...)
600
{
601
  (void)data; (void)cf; (void)fmt;
602
}
603
604
struct curl_trc_feat;
605
606
void Curl_trc_multi(struct Curl_easy *data, const char *fmt, ...)
607
{
608
  (void)data; (void)fmt;
609
}
610
611
void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
612
{
613
  (void)data; (void)fmt;
614
}
615
616
void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...)
617
{
618
  (void)data; (void)fmt;
619
}
620
621
void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
622
{
623
  (void)data; (void)fmt;
624
}
625
626
#ifndef CURL_DISABLE_FTP
627
void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
628
{
629
  (void)data; (void)fmt;
630
}
631
#endif
632
#ifndef CURL_DISABLE_SMTP
633
void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
634
{
635
  (void)data; (void)fmt;
636
}
637
#endif
638
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
639
void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
640
{
641
  (void)data; (void)fmt;
642
}
643
#endif
644
#ifdef USE_SSL
645
void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...)
646
{
647
  (void)data;
648
  (void)fmt;
649
}
650
#endif
651
652
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */