00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "setup.h"
00036
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #define _MPRINTF_REPLACE
00041 #include <curl/mprintf.h>
00042
00043 #include "urldata.h"
00044 #include "easyif.h"
00045 #include "base64.h"
00046 #include "memory.h"
00047
00048
00049 #include "memdebug.h"
00050
00051
00052 static const char table64[]=
00053 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00054
00055 static void decodeQuantum(unsigned char *dest, const char *src)
00056 {
00057 unsigned int x = 0;
00058 int i;
00059 char *found;
00060
00061 for(i = 0; i < 4; i++) {
00062 if((found = strchr(table64, src[i])) != NULL)
00063 x = (x << 6) + (unsigned int)(found - table64);
00064 else if(src[i] == '=')
00065 x = (x << 6);
00066 }
00067
00068 dest[2] = (unsigned char)(x & 255);
00069 x >>= 8;
00070 dest[1] = (unsigned char)(x & 255);
00071 x >>= 8;
00072 dest[0] = (unsigned char)(x & 255);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 size_t Curl_base64_decode(const char *src, unsigned char **outptr)
00082 {
00083 int length = 0;
00084 int equalsTerm = 0;
00085 int i;
00086 int numQuantums;
00087 unsigned char lastQuantum[3];
00088 size_t rawlen=0;
00089 unsigned char *newstr;
00090
00091 *outptr = NULL;
00092
00093 while((src[length] != '=') && src[length])
00094 length++;
00095
00096 if(src[length] == '=') {
00097 equalsTerm++;
00098 if(src[length+equalsTerm] == '=')
00099 equalsTerm++;
00100 }
00101 numQuantums = (length + equalsTerm) / 4;
00102
00103
00104 if (numQuantums <= 0)
00105 return 0;
00106
00107 rawlen = (numQuantums * 3) - equalsTerm;
00108
00109
00110
00111 newstr = malloc(rawlen+4);
00112 if(!newstr)
00113 return 0;
00114
00115 *outptr = newstr;
00116
00117
00118
00119 for(i = 0; i < numQuantums - 1; i++) {
00120 decodeQuantum((unsigned char *)newstr, src);
00121 newstr += 3; src += 4;
00122 }
00123
00124
00125
00126
00127 decodeQuantum(lastQuantum, src);
00128 for(i = 0; i < 3 - equalsTerm; i++)
00129 newstr[i] = lastQuantum[i];
00130
00131 newstr[i] = 0;
00132 return rawlen;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 size_t Curl_base64_encode(struct SessionHandle *data,
00144 const char *inp, size_t insize, char **outptr)
00145 {
00146 unsigned char ibuf[3];
00147 unsigned char obuf[4];
00148 int i;
00149 int inputparts;
00150 char *output;
00151 char *base64data;
00152 #ifdef CURL_DOES_CONVERSIONS
00153 char *convbuf = NULL;
00154 #endif
00155
00156 char *indata = (char *)inp;
00157
00158 *outptr = NULL;
00159
00160 if(0 == insize)
00161 insize = strlen(indata);
00162
00163 base64data = output = (char*)malloc(insize*4/3+4);
00164 if(NULL == output)
00165 return 0;
00166
00167 #ifdef CURL_DOES_CONVERSIONS
00168
00169
00170
00171
00172
00173 if(data) {
00174 convbuf = (char*)malloc(insize);
00175 if(!convbuf) {
00176 free(output);
00177 return 0;
00178 }
00179 memcpy(convbuf, indata, insize);
00180 if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
00181 free(convbuf);
00182 free(output);
00183 return 0;
00184 }
00185 indata = convbuf;
00186 }
00187 #else
00188 (void)data;
00189 #endif
00190
00191 while(insize > 0) {
00192 for (i = inputparts = 0; i < 3; i++) {
00193 if(insize > 0) {
00194 inputparts++;
00195 ibuf[i] = *indata;
00196 indata++;
00197 insize--;
00198 }
00199 else
00200 ibuf[i] = 0;
00201 }
00202
00203 obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
00204 obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
00205 ((ibuf[1] & 0xF0) >> 4));
00206 obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
00207 ((ibuf[2] & 0xC0) >> 6));
00208 obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
00209
00210 switch(inputparts) {
00211 case 1:
00212 snprintf(output, 5, "%c%c==",
00213 table64[obuf[0]],
00214 table64[obuf[1]]);
00215 break;
00216 case 2:
00217 snprintf(output, 5, "%c%c%c=",
00218 table64[obuf[0]],
00219 table64[obuf[1]],
00220 table64[obuf[2]]);
00221 break;
00222 default:
00223 snprintf(output, 5, "%c%c%c%c",
00224 table64[obuf[0]],
00225 table64[obuf[1]],
00226 table64[obuf[2]],
00227 table64[obuf[3]] );
00228 break;
00229 }
00230 output += 4;
00231 }
00232 *output=0;
00233 *outptr = base64data;
00234
00235 #ifdef CURL_DOES_CONVERSIONS
00236 if(data)
00237 free(convbuf);
00238 #endif
00239 return strlen(base64data);
00240 }
00241
00242
00243
00244
00245
00246 #ifdef TEST_ENCODE
00247
00248
00249
00250 #include <stdio.h>
00251
00252 #define TEST_NEED_SUCK
00253 void *suck(int *);
00254
00255 int main(int argc, argv_item_t argv[], char **envp)
00256 {
00257 char *base64;
00258 size_t base64Len;
00259 unsigned char *data;
00260 int dataLen;
00261 struct SessionHandle *handle = NULL;
00262
00263 #ifdef CURL_DOES_CONVERSIONS
00264
00265 handle = curl_easy_init();
00266 if(handle == NULL) {
00267 fprintf(stderr, "Error: curl_easy_init failed\n");
00268 return 0;
00269 }
00270 #endif
00271 data = (unsigned char *)suck(&dataLen);
00272 base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
00273
00274 fprintf(stderr, "%d\n", base64Len);
00275 fprintf(stdout, "%s\n", base64);
00276
00277 free(base64); free(data);
00278 #ifdef CURL_DOES_CONVERSIONS
00279 curl_easy_cleanup(handle);
00280 #endif
00281 return 0;
00282 }
00283 #endif
00284
00285 #ifdef TEST_DECODE
00286
00287
00288
00289
00290
00291 #include <stdio.h>
00292
00293 #define TEST_NEED_SUCK
00294 void *suck(int *);
00295
00296 int main(int argc, argv_item_t argv[], char **envp)
00297 {
00298 char *base64;
00299 int base64Len;
00300 unsigned char *data;
00301 int dataLen;
00302 int i, j;
00303 #ifdef CURL_DOES_CONVERSIONS
00304
00305 struct SessionHandle *handle = curl_easy_init();
00306 if(handle == NULL) {
00307 fprintf(stderr, "Error: curl_easy_init failed\n");
00308 return 0;
00309 }
00310 #endif
00311
00312 base64 = (char *)suck(&base64Len);
00313 dataLen = Curl_base64_decode(base64, &data);
00314
00315 fprintf(stderr, "%d\n", dataLen);
00316
00317 for(i=0; i < dataLen; i+=0x10) {
00318 printf("0x%02x: ", i);
00319 for(j=0; j < 0x10; j++)
00320 if((j+i) < dataLen)
00321 printf("%02x ", data[i+j]);
00322 else
00323 printf(" ");
00324
00325 printf(" | ");
00326
00327 for(j=0; j < 0x10; j++)
00328 if((j+i) < dataLen) {
00329 #ifdef CURL_DOES_CONVERSIONS
00330 if(CURLE_OK !=
00331 Curl_convert_from_network(handle, &data[i+j], (size_t)1))
00332 data[i+j] = '.';
00333 #endif
00334 printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
00335 } else
00336 break;
00337 puts("");
00338 }
00339
00340 #ifdef CURL_DOES_CONVERSIONS
00341 curl_easy_cleanup(handle);
00342 #endif
00343 free(base64); free(data);
00344 return 0;
00345 }
00346 #endif
00347
00348 #ifdef TEST_NEED_SUCK
00349
00350 void *suck(int *lenptr)
00351 {
00352 int cursize = 8192;
00353 unsigned char *buf = NULL;
00354 int lastread;
00355 int len = 0;
00356
00357 do {
00358 cursize *= 2;
00359 buf = (unsigned char *)realloc(buf, cursize);
00360 memset(buf + len, 0, cursize - len);
00361 lastread = fread(buf + len, 1, cursize - len, stdin);
00362 len += lastread;
00363 } while(!feof(stdin));
00364
00365 lenptr[0] = len;
00366 return (void *)buf;
00367 }
00368 #endif