first.h (7119B)
1 #ifndef HEADER_CLIENT_FIRST_H 2 #define HEADER_CLIENT_FIRST_H 3 /*************************************************************************** 4 * _ _ ____ _ 5 * Project ___| | | | _ \| | 6 * / __| | | | |_) | | 7 * | (__| |_| | _ <| |___ 8 * \___|\___/|_| \_\_____| 9 * 10 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 11 * 12 * This software is licensed as described in the file COPYING, which 13 * you should have received as part of this distribution. The terms 14 * are also available at https://curl.se/docs/copyright.html. 15 * 16 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 * copies of the Software, and permit persons to whom the Software is 18 * furnished to do so, under the terms of the COPYING file. 19 * 20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 * KIND, either express or implied. 22 * 23 * SPDX-License-Identifier: curl 24 * 25 ***************************************************************************/ 26 #include "curl_setup.h" 27 28 typedef int (*entry_func_t)(int, char **); 29 30 struct entry_s { 31 const char *name; 32 entry_func_t ptr; 33 }; 34 35 extern const struct entry_s s_entries[]; 36 37 #include <curl/curl.h> 38 39 #include <curlx/curlx.h> 40 41 #define ERR() \ 42 do { \ 43 curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n");\ 44 return 2; \ 45 } while(0) 46 47 static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) 48 { 49 /* 50 * This is the trace look that is similar to what libcurl makes on its 51 * own. 52 */ 53 static const char * const s_infotype[] = { 54 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " 55 }; 56 if(idsbuf && *idsbuf) 57 curl_mfprintf(log, "%s%s", idsbuf, s_infotype[type]); 58 else 59 fputs(s_infotype[type], log); 60 } 61 62 #define TRC_IDS_FORMAT_IDS_1 "[%" CURL_FORMAT_CURL_OFF_T "-x] " 63 #define TRC_IDS_FORMAT_IDS_2 "[%" CURL_FORMAT_CURL_OFF_T "-%" \ 64 CURL_FORMAT_CURL_OFF_T "] " 65 /* 66 ** callback for CURLOPT_DEBUGFUNCTION 67 */ 68 static int debug_cb(CURL *handle, curl_infotype type, 69 char *data, size_t size, void *userdata) 70 { 71 FILE *output = stderr; 72 static int newl = 0; 73 static int traced_data = 0; 74 char idsbuf[60]; 75 curl_off_t xfer_id, conn_id; 76 77 (void)handle; /* not used */ 78 (void)userdata; 79 80 if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { 81 if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && 82 conn_id >= 0) { 83 curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, xfer_id, 84 conn_id); 85 } 86 else { 87 curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id); 88 } 89 } 90 else 91 idsbuf[0] = 0; 92 93 switch(type) { 94 case CURLINFO_HEADER_OUT: 95 if(size > 0) { 96 size_t st = 0; 97 size_t i; 98 for(i = 0; i < size - 1; i++) { 99 if(data[i] == '\n') { /* LF */ 100 if(!newl) { 101 log_line_start(output, idsbuf, type); 102 } 103 (void)fwrite(data + st, i - st + 1, 1, output); 104 st = i + 1; 105 newl = 0; 106 } 107 } 108 if(!newl) 109 log_line_start(output, idsbuf, type); 110 (void)fwrite(data + st, i - st + 1, 1, output); 111 } 112 newl = (size && (data[size - 1] != '\n')) ? 1 : 0; 113 traced_data = 0; 114 break; 115 case CURLINFO_TEXT: 116 case CURLINFO_HEADER_IN: 117 if(!newl) 118 log_line_start(output, idsbuf, type); 119 (void)fwrite(data, size, 1, output); 120 newl = (size && (data[size - 1] != '\n')) ? 1 : 0; 121 traced_data = 0; 122 break; 123 case CURLINFO_DATA_OUT: 124 case CURLINFO_DATA_IN: 125 case CURLINFO_SSL_DATA_IN: 126 case CURLINFO_SSL_DATA_OUT: 127 if(!traced_data) { 128 if(!newl) 129 log_line_start(output, idsbuf, type); 130 curl_mfprintf(output, "[%ld bytes data]\n", (long)size); 131 newl = 0; 132 traced_data = 1; 133 } 134 break; 135 default: /* nada */ 136 newl = 0; 137 traced_data = 1; 138 break; 139 } 140 141 return 0; 142 } 143 144 static void dump(const char *text, unsigned char *ptr, size_t size, char nohex) 145 { 146 size_t i; 147 size_t c; 148 149 unsigned int width = 0x10; 150 151 if(nohex) 152 /* without the hex output, we can fit more on screen */ 153 width = 0x40; 154 155 curl_mfprintf(stderr, "%s, %lu bytes (0x%lx)\n", 156 text, (unsigned long)size, (unsigned long)size); 157 158 for(i = 0; i < size; i += width) { 159 160 curl_mfprintf(stderr, "%4.4lx: ", (unsigned long)i); 161 162 if(!nohex) { 163 /* hex not disabled, show it */ 164 for(c = 0; c < width; c++) 165 if(i + c < size) 166 curl_mfprintf(stderr, "%02x ", ptr[i + c]); 167 else 168 fputs(" ", stderr); 169 } 170 171 for(c = 0; (c < width) && (i + c < size); c++) { 172 /* check for 0D0A; if found, skip past and start a new line of output */ 173 if(nohex && (i + c + 1 < size) && ptr[i + c] == 0x0D && 174 ptr[i + c + 1] == 0x0A) { 175 i += (c + 2 - width); 176 break; 177 } 178 curl_mfprintf(stderr, "%c", 179 (ptr[i + c] >= 0x20) && (ptr[i + c] < 0x80) ? ptr[i + c] : '.'); 180 /* check again for 0D0A, to avoid an extra \n if it's at width */ 181 if(nohex && (i + c + 2 < size) && ptr[i + c + 1] == 0x0D && 182 ptr[i + c + 2] == 0x0A) { 183 i += (c + 3 - width); 184 break; 185 } 186 } 187 fputc('\n', stderr); /* newline */ 188 } 189 } 190 191 #ifndef CURL_DISABLE_WEBSOCKETS 192 /* just close the connection */ 193 static void websocket_close(CURL *curl) 194 { 195 size_t sent; 196 CURLcode result = 197 curl_ws_send(curl, "", 0, &sent, 0, CURLWS_CLOSE); 198 curl_mfprintf(stderr, "ws: curl_ws_send returned %u, sent %u\n", 199 (int)result, (int)sent); 200 } 201 #endif /* CURL_DISABLE_WEBSOCKETS */ 202 203 static int coptind; 204 static char *coptarg; 205 206 static int cgetopt(int argc, char * const argv[], const char *optstring) 207 { 208 static int optpos = 1; 209 int coptopt; 210 char *arg; 211 212 if(coptind == 0) { /* Reset? */ 213 coptind = !!argc; 214 optpos = 1; 215 } 216 217 arg = argv[coptind]; 218 if(arg && strcmp(arg, "--") == 0) { 219 coptind++; 220 return -1; 221 } 222 else if(!arg || arg[0] != '-') { 223 return -1; 224 } 225 else { 226 const char *opt = strchr(optstring, arg[optpos]); 227 coptopt = arg[optpos]; 228 if(!opt) { 229 if(!arg[++optpos]) { 230 coptind++; 231 optpos = 1; 232 } 233 return '?'; 234 } 235 else if(opt[1] == ':') { 236 if(arg[optpos + 1]) { 237 coptarg = arg + optpos + 1; 238 coptind++; 239 optpos = 1; 240 return coptopt; 241 } 242 else if(argv[coptind + 1]) { 243 coptarg = argv[coptind + 1]; 244 coptind += 2; 245 optpos = 1; 246 return coptopt; 247 } 248 else { 249 if(!arg[++optpos]) { 250 coptind++; 251 optpos = 1; 252 } 253 return *optstring == ':' ? ':' : '?'; 254 } 255 } 256 else { 257 if(!arg[++optpos]) { 258 coptind++; 259 optpos = 1; 260 } 261 return coptopt; 262 } 263 } 264 } 265 266 #endif /* HEADER_CLIENT_FIRST_H */