xref: /aosp_15_r20/external/curl/src/tool_cb_dbg.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker  *                                  _   _ ____  _
3*6236dae4SAndroid Build Coastguard Worker  *  Project                     ___| | | |  _ \| |
4*6236dae4SAndroid Build Coastguard Worker  *                             / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker  *                            | (__| |_| |  _ <| |___
6*6236dae4SAndroid Build Coastguard Worker  *                             \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker  *
8*6236dae4SAndroid Build Coastguard Worker  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker  *
10*6236dae4SAndroid Build Coastguard Worker  * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker  * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker  * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker  *
14*6236dae4SAndroid Build Coastguard Worker  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker  * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker  * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker  *
18*6236dae4SAndroid Build Coastguard Worker  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker  * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker  *
21*6236dae4SAndroid Build Coastguard Worker  * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker  *
23*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "tool_setup.h"
25*6236dae4SAndroid Build Coastguard Worker 
26*6236dae4SAndroid Build Coastguard Worker #include "curlx.h"
27*6236dae4SAndroid Build Coastguard Worker 
28*6236dae4SAndroid Build Coastguard Worker #include "tool_cfgable.h"
29*6236dae4SAndroid Build Coastguard Worker #include "tool_msgs.h"
30*6236dae4SAndroid Build Coastguard Worker #include "tool_cb_dbg.h"
31*6236dae4SAndroid Build Coastguard Worker #include "tool_util.h"
32*6236dae4SAndroid Build Coastguard Worker 
33*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h" /* keep this as LAST include */
34*6236dae4SAndroid Build Coastguard Worker 
35*6236dae4SAndroid Build Coastguard Worker static void dump(const char *timebuf, const char *idsbuf, const char *text,
36*6236dae4SAndroid Build Coastguard Worker                  FILE *stream, const unsigned char *ptr, size_t size,
37*6236dae4SAndroid Build Coastguard Worker                  trace tracetype, curl_infotype infotype);
38*6236dae4SAndroid Build Coastguard Worker 
39*6236dae4SAndroid Build Coastguard Worker /*
40*6236dae4SAndroid Build Coastguard Worker  * Return the formatted HH:MM:SS for the tv_sec given.
41*6236dae4SAndroid Build Coastguard Worker  * NOT thread safe.
42*6236dae4SAndroid Build Coastguard Worker  */
hms_for_sec(time_t tv_sec)43*6236dae4SAndroid Build Coastguard Worker static const char *hms_for_sec(time_t tv_sec)
44*6236dae4SAndroid Build Coastguard Worker {
45*6236dae4SAndroid Build Coastguard Worker   static time_t cached_tv_sec;
46*6236dae4SAndroid Build Coastguard Worker   static char hms_buf[12];
47*6236dae4SAndroid Build Coastguard Worker   static time_t epoch_offset;
48*6236dae4SAndroid Build Coastguard Worker   static int known_epoch;
49*6236dae4SAndroid Build Coastguard Worker 
50*6236dae4SAndroid Build Coastguard Worker   if(tv_sec != cached_tv_sec) {
51*6236dae4SAndroid Build Coastguard Worker     struct tm *now;
52*6236dae4SAndroid Build Coastguard Worker     time_t secs;
53*6236dae4SAndroid Build Coastguard Worker     /* recalculate */
54*6236dae4SAndroid Build Coastguard Worker     if(!known_epoch) {
55*6236dae4SAndroid Build Coastguard Worker       epoch_offset = time(NULL) - tv_sec;
56*6236dae4SAndroid Build Coastguard Worker       known_epoch = 1;
57*6236dae4SAndroid Build Coastguard Worker     }
58*6236dae4SAndroid Build Coastguard Worker     secs = epoch_offset + tv_sec;
59*6236dae4SAndroid Build Coastguard Worker     /* !checksrc! disable BANNEDFUNC 1 */
60*6236dae4SAndroid Build Coastguard Worker     now = localtime(&secs);  /* not thread safe but we do not care */
61*6236dae4SAndroid Build Coastguard Worker     msnprintf(hms_buf, sizeof(hms_buf), "%02d:%02d:%02d",
62*6236dae4SAndroid Build Coastguard Worker               now->tm_hour, now->tm_min, now->tm_sec);
63*6236dae4SAndroid Build Coastguard Worker     cached_tv_sec = tv_sec;
64*6236dae4SAndroid Build Coastguard Worker   }
65*6236dae4SAndroid Build Coastguard Worker   return hms_buf;
66*6236dae4SAndroid Build Coastguard Worker }
67*6236dae4SAndroid Build Coastguard Worker 
log_line_start(FILE * log,const char * timebuf,const char * idsbuf,curl_infotype type)68*6236dae4SAndroid Build Coastguard Worker static void log_line_start(FILE *log, const char *timebuf,
69*6236dae4SAndroid Build Coastguard Worker                            const char *idsbuf, curl_infotype type)
70*6236dae4SAndroid Build Coastguard Worker {
71*6236dae4SAndroid Build Coastguard Worker   /*
72*6236dae4SAndroid Build Coastguard Worker    * This is the trace look that is similar to what libcurl makes on its
73*6236dae4SAndroid Build Coastguard Worker    * own.
74*6236dae4SAndroid Build Coastguard Worker    */
75*6236dae4SAndroid Build Coastguard Worker   static const char * const s_infotype[] = {
76*6236dae4SAndroid Build Coastguard Worker     "* ", "< ", "> ", "{ ", "} ", "{ ", "} "
77*6236dae4SAndroid Build Coastguard Worker   };
78*6236dae4SAndroid Build Coastguard Worker   if((timebuf && *timebuf) || (idsbuf && *idsbuf))
79*6236dae4SAndroid Build Coastguard Worker     fprintf(log, "%s%s%s", timebuf, idsbuf, s_infotype[type]);
80*6236dae4SAndroid Build Coastguard Worker   else
81*6236dae4SAndroid Build Coastguard Worker     fputs(s_infotype[type], log);
82*6236dae4SAndroid Build Coastguard Worker }
83*6236dae4SAndroid Build Coastguard Worker 
84*6236dae4SAndroid Build Coastguard Worker #define TRC_IDS_FORMAT_IDS_1  "[%" CURL_FORMAT_CURL_OFF_T "-x] "
85*6236dae4SAndroid Build Coastguard Worker #define TRC_IDS_FORMAT_IDS_2  "[%" CURL_FORMAT_CURL_OFF_T "-%" \
86*6236dae4SAndroid Build Coastguard Worker                                    CURL_FORMAT_CURL_OFF_T "] "
87*6236dae4SAndroid Build Coastguard Worker /*
88*6236dae4SAndroid Build Coastguard Worker ** callback for CURLOPT_DEBUGFUNCTION
89*6236dae4SAndroid Build Coastguard Worker */
tool_debug_cb(CURL * handle,curl_infotype type,char * data,size_t size,void * userdata)90*6236dae4SAndroid Build Coastguard Worker int tool_debug_cb(CURL *handle, curl_infotype type,
91*6236dae4SAndroid Build Coastguard Worker                   char *data, size_t size,
92*6236dae4SAndroid Build Coastguard Worker                   void *userdata)
93*6236dae4SAndroid Build Coastguard Worker {
94*6236dae4SAndroid Build Coastguard Worker   struct OperationConfig *operation = userdata;
95*6236dae4SAndroid Build Coastguard Worker   struct GlobalConfig *config = operation->global;
96*6236dae4SAndroid Build Coastguard Worker   FILE *output = tool_stderr;
97*6236dae4SAndroid Build Coastguard Worker   const char *text;
98*6236dae4SAndroid Build Coastguard Worker   struct timeval tv;
99*6236dae4SAndroid Build Coastguard Worker   char timebuf[20];
100*6236dae4SAndroid Build Coastguard Worker   /* largest signed 64-bit is: 9,223,372,036,854,775,807
101*6236dae4SAndroid Build Coastguard Worker    * max length in decimal: 1 + (6*3) = 19
102*6236dae4SAndroid Build Coastguard Worker    * formatted via TRC_IDS_FORMAT_IDS_2 this becomes 2 + 19 + 1 + 19 + 2 = 43
103*6236dae4SAndroid Build Coastguard Worker    * negative xfer-id are not printed, negative conn-ids use TRC_IDS_FORMAT_1
104*6236dae4SAndroid Build Coastguard Worker    */
105*6236dae4SAndroid Build Coastguard Worker   char idsbuf[60];
106*6236dae4SAndroid Build Coastguard Worker   curl_off_t xfer_id, conn_id;
107*6236dae4SAndroid Build Coastguard Worker 
108*6236dae4SAndroid Build Coastguard Worker   (void)handle; /* not used */
109*6236dae4SAndroid Build Coastguard Worker 
110*6236dae4SAndroid Build Coastguard Worker   if(config->tracetime) {
111*6236dae4SAndroid Build Coastguard Worker     tv = tvnow();
112*6236dae4SAndroid Build Coastguard Worker     msnprintf(timebuf, sizeof(timebuf), "%s.%06ld ",
113*6236dae4SAndroid Build Coastguard Worker               hms_for_sec(tv.tv_sec), (long)tv.tv_usec);
114*6236dae4SAndroid Build Coastguard Worker   }
115*6236dae4SAndroid Build Coastguard Worker   else
116*6236dae4SAndroid Build Coastguard Worker     timebuf[0] = 0;
117*6236dae4SAndroid Build Coastguard Worker 
118*6236dae4SAndroid Build Coastguard Worker   if(handle && config->traceids &&
119*6236dae4SAndroid Build Coastguard Worker      !curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) {
120*6236dae4SAndroid Build Coastguard Worker     if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) &&
121*6236dae4SAndroid Build Coastguard Worker         conn_id >= 0) {
122*6236dae4SAndroid Build Coastguard Worker       msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2,
123*6236dae4SAndroid Build Coastguard Worker                 xfer_id, conn_id);
124*6236dae4SAndroid Build Coastguard Worker     }
125*6236dae4SAndroid Build Coastguard Worker     else {
126*6236dae4SAndroid Build Coastguard Worker       msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id);
127*6236dae4SAndroid Build Coastguard Worker     }
128*6236dae4SAndroid Build Coastguard Worker   }
129*6236dae4SAndroid Build Coastguard Worker   else
130*6236dae4SAndroid Build Coastguard Worker     idsbuf[0] = 0;
131*6236dae4SAndroid Build Coastguard Worker 
132*6236dae4SAndroid Build Coastguard Worker   if(!config->trace_stream) {
133*6236dae4SAndroid Build Coastguard Worker     /* open for append */
134*6236dae4SAndroid Build Coastguard Worker     if(!strcmp("-", config->trace_dump))
135*6236dae4SAndroid Build Coastguard Worker       config->trace_stream = stdout;
136*6236dae4SAndroid Build Coastguard Worker     else if(!strcmp("%", config->trace_dump))
137*6236dae4SAndroid Build Coastguard Worker       /* Ok, this is somewhat hackish but we do it undocumented for now */
138*6236dae4SAndroid Build Coastguard Worker       config->trace_stream = tool_stderr;
139*6236dae4SAndroid Build Coastguard Worker     else {
140*6236dae4SAndroid Build Coastguard Worker       config->trace_stream = fopen(config->trace_dump, FOPEN_WRITETEXT);
141*6236dae4SAndroid Build Coastguard Worker       config->trace_fopened = TRUE;
142*6236dae4SAndroid Build Coastguard Worker     }
143*6236dae4SAndroid Build Coastguard Worker   }
144*6236dae4SAndroid Build Coastguard Worker 
145*6236dae4SAndroid Build Coastguard Worker   if(config->trace_stream)
146*6236dae4SAndroid Build Coastguard Worker     output = config->trace_stream;
147*6236dae4SAndroid Build Coastguard Worker 
148*6236dae4SAndroid Build Coastguard Worker   if(!output) {
149*6236dae4SAndroid Build Coastguard Worker     warnf(config, "Failed to create/open output");
150*6236dae4SAndroid Build Coastguard Worker     return 0;
151*6236dae4SAndroid Build Coastguard Worker   }
152*6236dae4SAndroid Build Coastguard Worker 
153*6236dae4SAndroid Build Coastguard Worker   if(config->tracetype == TRACE_PLAIN) {
154*6236dae4SAndroid Build Coastguard Worker     static bool newl = FALSE;
155*6236dae4SAndroid Build Coastguard Worker     static bool traced_data = FALSE;
156*6236dae4SAndroid Build Coastguard Worker 
157*6236dae4SAndroid Build Coastguard Worker     switch(type) {
158*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_HEADER_OUT:
159*6236dae4SAndroid Build Coastguard Worker       if(size > 0) {
160*6236dae4SAndroid Build Coastguard Worker         size_t st = 0;
161*6236dae4SAndroid Build Coastguard Worker         size_t i;
162*6236dae4SAndroid Build Coastguard Worker         for(i = 0; i < size - 1; i++) {
163*6236dae4SAndroid Build Coastguard Worker           if(data[i] == '\n') { /* LF */
164*6236dae4SAndroid Build Coastguard Worker             if(!newl) {
165*6236dae4SAndroid Build Coastguard Worker               log_line_start(output, timebuf, idsbuf, type);
166*6236dae4SAndroid Build Coastguard Worker             }
167*6236dae4SAndroid Build Coastguard Worker             (void)fwrite(data + st, i - st + 1, 1, output);
168*6236dae4SAndroid Build Coastguard Worker             st = i + 1;
169*6236dae4SAndroid Build Coastguard Worker             newl = FALSE;
170*6236dae4SAndroid Build Coastguard Worker           }
171*6236dae4SAndroid Build Coastguard Worker         }
172*6236dae4SAndroid Build Coastguard Worker         if(!newl)
173*6236dae4SAndroid Build Coastguard Worker           log_line_start(output, timebuf, idsbuf, type);
174*6236dae4SAndroid Build Coastguard Worker         (void)fwrite(data + st, i - st + 1, 1, output);
175*6236dae4SAndroid Build Coastguard Worker       }
176*6236dae4SAndroid Build Coastguard Worker       newl = (size && (data[size - 1] != '\n'));
177*6236dae4SAndroid Build Coastguard Worker       traced_data = FALSE;
178*6236dae4SAndroid Build Coastguard Worker       break;
179*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_TEXT:
180*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_HEADER_IN:
181*6236dae4SAndroid Build Coastguard Worker       if(!newl)
182*6236dae4SAndroid Build Coastguard Worker         log_line_start(output, timebuf, idsbuf, type);
183*6236dae4SAndroid Build Coastguard Worker       (void)fwrite(data, size, 1, output);
184*6236dae4SAndroid Build Coastguard Worker       newl = (size && (data[size - 1] != '\n'));
185*6236dae4SAndroid Build Coastguard Worker       traced_data = FALSE;
186*6236dae4SAndroid Build Coastguard Worker       break;
187*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_DATA_OUT:
188*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_DATA_IN:
189*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_SSL_DATA_IN:
190*6236dae4SAndroid Build Coastguard Worker     case CURLINFO_SSL_DATA_OUT:
191*6236dae4SAndroid Build Coastguard Worker       if(!traced_data) {
192*6236dae4SAndroid Build Coastguard Worker         /* if the data is output to a tty and we are sending this debug trace
193*6236dae4SAndroid Build Coastguard Worker            to stderr or stdout, we do not display the alert about the data not
194*6236dae4SAndroid Build Coastguard Worker            being shown as the data _is_ shown then just not via this
195*6236dae4SAndroid Build Coastguard Worker            function */
196*6236dae4SAndroid Build Coastguard Worker         if(!config->isatty ||
197*6236dae4SAndroid Build Coastguard Worker            ((output != tool_stderr) && (output != stdout))) {
198*6236dae4SAndroid Build Coastguard Worker           if(!newl)
199*6236dae4SAndroid Build Coastguard Worker             log_line_start(output, timebuf, idsbuf, type);
200*6236dae4SAndroid Build Coastguard Worker           fprintf(output, "[%zu bytes data]\n", size);
201*6236dae4SAndroid Build Coastguard Worker           newl = FALSE;
202*6236dae4SAndroid Build Coastguard Worker           traced_data = TRUE;
203*6236dae4SAndroid Build Coastguard Worker         }
204*6236dae4SAndroid Build Coastguard Worker       }
205*6236dae4SAndroid Build Coastguard Worker       break;
206*6236dae4SAndroid Build Coastguard Worker     default: /* nada */
207*6236dae4SAndroid Build Coastguard Worker       newl = FALSE;
208*6236dae4SAndroid Build Coastguard Worker       traced_data = FALSE;
209*6236dae4SAndroid Build Coastguard Worker       break;
210*6236dae4SAndroid Build Coastguard Worker     }
211*6236dae4SAndroid Build Coastguard Worker 
212*6236dae4SAndroid Build Coastguard Worker     return 0;
213*6236dae4SAndroid Build Coastguard Worker   }
214*6236dae4SAndroid Build Coastguard Worker 
215*6236dae4SAndroid Build Coastguard Worker   switch(type) {
216*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_TEXT:
217*6236dae4SAndroid Build Coastguard Worker     fprintf(output, "%s%s== Info: %.*s", timebuf, idsbuf, (int)size, data);
218*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
219*6236dae4SAndroid Build Coastguard Worker   default: /* in case a new one is introduced to shock us */
220*6236dae4SAndroid Build Coastguard Worker     return 0;
221*6236dae4SAndroid Build Coastguard Worker 
222*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_HEADER_OUT:
223*6236dae4SAndroid Build Coastguard Worker     text = "=> Send header";
224*6236dae4SAndroid Build Coastguard Worker     break;
225*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_DATA_OUT:
226*6236dae4SAndroid Build Coastguard Worker     text = "=> Send data";
227*6236dae4SAndroid Build Coastguard Worker     break;
228*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_HEADER_IN:
229*6236dae4SAndroid Build Coastguard Worker     text = "<= Recv header";
230*6236dae4SAndroid Build Coastguard Worker     break;
231*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_DATA_IN:
232*6236dae4SAndroid Build Coastguard Worker     text = "<= Recv data";
233*6236dae4SAndroid Build Coastguard Worker     break;
234*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_SSL_DATA_IN:
235*6236dae4SAndroid Build Coastguard Worker     text = "<= Recv SSL data";
236*6236dae4SAndroid Build Coastguard Worker     break;
237*6236dae4SAndroid Build Coastguard Worker   case CURLINFO_SSL_DATA_OUT:
238*6236dae4SAndroid Build Coastguard Worker     text = "=> Send SSL data";
239*6236dae4SAndroid Build Coastguard Worker     break;
240*6236dae4SAndroid Build Coastguard Worker   }
241*6236dae4SAndroid Build Coastguard Worker 
242*6236dae4SAndroid Build Coastguard Worker   dump(timebuf, idsbuf, text, output, (unsigned char *) data, size,
243*6236dae4SAndroid Build Coastguard Worker        config->tracetype, type);
244*6236dae4SAndroid Build Coastguard Worker   return 0;
245*6236dae4SAndroid Build Coastguard Worker }
246*6236dae4SAndroid Build Coastguard Worker 
dump(const char * timebuf,const char * idsbuf,const char * text,FILE * stream,const unsigned char * ptr,size_t size,trace tracetype,curl_infotype infotype)247*6236dae4SAndroid Build Coastguard Worker static void dump(const char *timebuf, const char *idsbuf, const char *text,
248*6236dae4SAndroid Build Coastguard Worker                  FILE *stream, const unsigned char *ptr, size_t size,
249*6236dae4SAndroid Build Coastguard Worker                  trace tracetype, curl_infotype infotype)
250*6236dae4SAndroid Build Coastguard Worker {
251*6236dae4SAndroid Build Coastguard Worker   size_t i;
252*6236dae4SAndroid Build Coastguard Worker   size_t c;
253*6236dae4SAndroid Build Coastguard Worker 
254*6236dae4SAndroid Build Coastguard Worker   unsigned int width = 0x10;
255*6236dae4SAndroid Build Coastguard Worker 
256*6236dae4SAndroid Build Coastguard Worker   if(tracetype == TRACE_ASCII)
257*6236dae4SAndroid Build Coastguard Worker     /* without the hex output, we can fit more on screen */
258*6236dae4SAndroid Build Coastguard Worker     width = 0x40;
259*6236dae4SAndroid Build Coastguard Worker 
260*6236dae4SAndroid Build Coastguard Worker   fprintf(stream, "%s%s%s, %zu bytes (0x%zx)\n", timebuf, idsbuf,
261*6236dae4SAndroid Build Coastguard Worker           text, size, size);
262*6236dae4SAndroid Build Coastguard Worker 
263*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < size; i += width) {
264*6236dae4SAndroid Build Coastguard Worker 
265*6236dae4SAndroid Build Coastguard Worker     fprintf(stream, "%04zx: ", i);
266*6236dae4SAndroid Build Coastguard Worker 
267*6236dae4SAndroid Build Coastguard Worker     if(tracetype == TRACE_BIN) {
268*6236dae4SAndroid Build Coastguard Worker       /* hex not disabled, show it */
269*6236dae4SAndroid Build Coastguard Worker       for(c = 0; c < width; c++)
270*6236dae4SAndroid Build Coastguard Worker         if(i + c < size)
271*6236dae4SAndroid Build Coastguard Worker           fprintf(stream, "%02x ", ptr[i + c]);
272*6236dae4SAndroid Build Coastguard Worker         else
273*6236dae4SAndroid Build Coastguard Worker           fputs("   ", stream);
274*6236dae4SAndroid Build Coastguard Worker     }
275*6236dae4SAndroid Build Coastguard Worker 
276*6236dae4SAndroid Build Coastguard Worker     for(c = 0; (c < width) && (i + c < size); c++) {
277*6236dae4SAndroid Build Coastguard Worker       /* check for 0D0A; if found, skip past and start a new line of output */
278*6236dae4SAndroid Build Coastguard Worker       if((tracetype == TRACE_ASCII) &&
279*6236dae4SAndroid Build Coastguard Worker          (i + c + 1 < size) && (ptr[i + c] == 0x0D) &&
280*6236dae4SAndroid Build Coastguard Worker          (ptr[i + c + 1] == 0x0A)) {
281*6236dae4SAndroid Build Coastguard Worker         i += (c + 2 - width);
282*6236dae4SAndroid Build Coastguard Worker         break;
283*6236dae4SAndroid Build Coastguard Worker       }
284*6236dae4SAndroid Build Coastguard Worker       (void)infotype;
285*6236dae4SAndroid Build Coastguard Worker       fprintf(stream, "%c", ((ptr[i + c] >= 0x20) && (ptr[i + c] < 0x7F)) ?
286*6236dae4SAndroid Build Coastguard Worker               ptr[i + c] : UNPRINTABLE_CHAR);
287*6236dae4SAndroid Build Coastguard Worker       /* check again for 0D0A, to avoid an extra \n if it is at width */
288*6236dae4SAndroid Build Coastguard Worker       if((tracetype == TRACE_ASCII) &&
289*6236dae4SAndroid Build Coastguard Worker          (i + c + 2 < size) && (ptr[i + c + 1] == 0x0D) &&
290*6236dae4SAndroid Build Coastguard Worker          (ptr[i + c + 2] == 0x0A)) {
291*6236dae4SAndroid Build Coastguard Worker         i += (c + 3 - width);
292*6236dae4SAndroid Build Coastguard Worker         break;
293*6236dae4SAndroid Build Coastguard Worker       }
294*6236dae4SAndroid Build Coastguard Worker     }
295*6236dae4SAndroid Build Coastguard Worker     fputc('\n', stream); /* newline */
296*6236dae4SAndroid Build Coastguard Worker   }
297*6236dae4SAndroid Build Coastguard Worker   fflush(stream);
298*6236dae4SAndroid Build Coastguard Worker }
299