summaryrefslogtreecommitdiffabout
path: root/lib/trace.c
blob: 6b79e58621be919b52304cede0e83176be348df0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* This file is part of Eclat.
   Copyright (C) 2012-2018 Sergey Poznyakoff.
 
   Eclat is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.
 
   Eclat is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with Eclat.  If not, see <http://www.gnu.org/licenses/>. */

#include "libeclat.h"
#include <ctype.h>
#include <curl/curl.h>

static void
dump(const char *text, FILE *stream, unsigned char *ptr, size_t size, int hex)
{
	size_t i;
	size_t c;
	unsigned int width = 0x10;
		
	if (!hex)
		/* without the hex output, we can fit more on screen */
		width = 0x40;

	fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);

	for (i = 0; i < size; i += width) {
		fprintf(stream, "%04zx: ", i);

		if (hex) {
			for (c = 0; c < width; c++)
				if (i+c < size)
					fprintf(stream, "%02x ", ptr[i+c]);
				else
					fputs("   ", stream);
		}

		for (c = 0; (c < width) && (i+c < size); c++) {
			/* check for CRLf; if found, skip past and start a
			   new line of output */
			if (!hex && (i + c + 1 < size) &&
			    ptr[i+c] == '\r' && ptr[i+c+1] == '\n') {
				i += (c + 2 -width);
				break;
			}
			fprintf(stream, "%c",
				isprint(ptr[i+c]) ? ptr[i+c] : '.');
			/* check again for CRLF, to avoid an extra \n if
			   it's at width */
			if (!hex && (i + c + 2 < size) &&
			    ptr[i+c+1] == '\r' && ptr[i+c+2] == '\n') {
				i += (c + 3 - width);
				break;
			}
		}
		fputc('\n', stream);
	}
	fflush(stream);
}

int
eclat_trace_fun(CURL *handle, curl_infotype type,
		char *data, size_t size,
		void *userp)
{
	int hex;
	const char *text;

	hex = !!userp;

	switch (type) {
	case CURLINFO_TEXT:
		fprintf(stderr, "== Info: %s", data);
	default: /* in case a new one is introduced to shock us */
		return 0;

	case CURLINFO_HEADER_OUT:
		text = "=> Send header";
		break;
	case CURLINFO_DATA_OUT:
		text = "=> Send data";
		break;
	case CURLINFO_SSL_DATA_OUT:
		text = "=> Send SSL data";
		break;
	case CURLINFO_HEADER_IN:
		text = "<= Recv header";
		break;
	case CURLINFO_DATA_IN:
		text = "<= Recv data";
		break;
	case CURLINFO_SSL_DATA_IN:
		text = "<= Recv SSL data";
		break;
	}
	
	dump(text, stderr, (unsigned char *)data, size, hex);
	return 0;
}

void
eclat_set_curl_trace(CURL *curl, int lev)
{
	if (lev == 0)
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
	else {
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
		if (lev > 1) {
			curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
					 eclat_trace_fun);
			if (lev > 2)
				curl_easy_setopt(curl, CURLOPT_DEBUGDATA, 1L);
		}
	}
}

Return to:

Send suggestions and report system problems to the System administrator.