summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Friloux <guillaume.friloux@gmail.com>2013-08-15 08:10:33 +0200
committerGuillaume Friloux <guillaume.friloux@gmail.com>2013-08-15 08:10:33 +0200
commit7c8d5d233cbc45c0dd93c058899e0cae218a412e (patch)
treee339f3bbf282fd4bce58506d948d3416e7e28794
parent861424f3d1e05e82c5ccfb660491e7d794d87413 (diff)
Lots of fixes
- Fixed mega's URL (they changed it, dont know when) - Fixed base64 encoding lib to match what does mega. - Fixed date sending (dont send json data, you have to put '[]' around it) - Added Default API KEY (its something that was put at same time as new URL) I have yet to implement : - proper id generator for URL - configurable API KEY - Decode json answer from login properly - Return an error event if auth failed - Return a connection event if auth succeeded
-rw-r--r--src/bin/main.c4
-rw-r--r--src/include/Skypunch.h3
-rw-r--r--src/include/extra/aes.h (renamed from src/lib/extra/aes.h)0
-rw-r--r--src/include/extra/cJSON.h128
-rw-r--r--src/include/extra/cencode.h38
-rw-r--r--src/include/skypunch_private.h (renamed from src/lib/skypunch_private.h)2
-rw-r--r--src/lib/Makefile.mk20
-rw-r--r--src/lib/extra/cJSON.c524
-rw-r--r--src/lib/extra/cencode.c110
-rw-r--r--src/lib/skypunch_main.c11
-rw-r--r--src/modules/Makefile.mk12
-rw-r--r--src/modules/mega/mega.h39
-rw-r--r--src/modules/mega/mega_event.c25
-rw-r--r--src/modules/mega/mega_login.c68
-rw-r--r--src/modules/mega/mega_main.c38
-rw-r--r--src/modules/mega/mega_utils.c43
16 files changed, 1024 insertions, 41 deletions
diff --git a/src/bin/main.c b/src/bin/main.c
index 9ca2ba9..04acc41 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -9,8 +9,8 @@ int main(int argc, char **argv)
9 return 1; 9 return 1;
10 10
11 skypunch_init(); 11 skypunch_init();
12 skypunch = skypunch_new(SKYPUNCH_MEGA, argv[1]); 12 skypunch = skypunch_new(SKYPUNCH_MEGA);
13 skypunch_login(skypunch); 13 skypunch_login(skypunch, argv[1]);
14 14
15 ecore_main_loop_begin(); 15 ecore_main_loop_begin();
16 16
diff --git a/src/include/Skypunch.h b/src/include/Skypunch.h
index 42f854e..dfb4e98 100644
--- a/src/include/Skypunch.h
+++ b/src/include/Skypunch.h
@@ -9,8 +9,9 @@ typedef enum _Skypunch_Type
9 9
10typedef struct _Skypunch Skypunch; 10typedef struct _Skypunch Skypunch;
11 11
12Skypunch * skypunch_new(Skypunch_Type type, const char *auth); 12Skypunch * skypunch_new(Skypunch_Type type);
13void skypunch_free(Skypunch *skypunch); 13void skypunch_free(Skypunch *skypunch);
14int skypunch_init(void); 14int skypunch_init(void);
15int skypunch_shutdown(void); 15int skypunch_shutdown(void);
16 16
17Eina_Bool skypunch_login(Skypunch *skypunch, const char *auth);
diff --git a/src/lib/extra/aes.h b/src/include/extra/aes.h
index 25721c8..25721c8 100644
--- a/src/lib/extra/aes.h
+++ b/src/include/extra/aes.h
diff --git a/src/include/extra/cJSON.h b/src/include/extra/cJSON.h
new file mode 100644
index 0000000..193755c
--- /dev/null
+++ b/src/include/extra/cJSON.h
@@ -0,0 +1,128 @@
1/*
2 Copyright (c) 2009 Dave Gamble
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21*/
22
23#ifndef cJSON__h
24#define cJSON__h
25
26#include <stdlib.h>
27#ifdef __cplusplus
28extern "C"
29{
30#endif
31
32/* cJSON Types: */
33#define cJSON_False 0
34#define cJSON_True 1
35#define cJSON_NULL 2
36#define cJSON_Number 3
37#define cJSON_String 4
38#define cJSON_Array 5
39#define cJSON_Object 6
40
41#define cJSON_IsReference 256
42
43/* The cJSON structure: */
44typedef struct cJSON {
45 struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
46 struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
47
48 int type; /* The type of the item, as above. */
49
50 char *valuestring; /* The item's string, if type==cJSON_String */
51 int valueint; /* The item's number, if type==cJSON_Number */
52 double valuedouble; /* The item's number, if type==cJSON_Number */
53
54 char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
55} cJSON;
56
57typedef struct cJSON_Hooks {
58 void *(*malloc_fn)(size_t sz);
59 void (*free_fn)(void *ptr);
60} cJSON_Hooks;
61
62/* Supply malloc, realloc and free functions to cJSON */
63extern void cJSON_InitHooks(cJSON_Hooks* hooks);
64
65
66/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
67extern cJSON *cJSON_Parse(const char *value);
68/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
69extern char *cJSON_Print(cJSON *item);
70/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
71extern char *cJSON_PrintUnformatted(cJSON *item);
72/* Delete a cJSON entity and all subentities. */
73extern void cJSON_Delete(cJSON *c);
74
75/* Returns the number of items in an array (or object). */
76extern int cJSON_GetArraySize(cJSON *array);
77/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
78extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
79/* Get item "string" from object. Case insensitive. */
80extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
81
82/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
83extern const char *cJSON_GetErrorPtr();
84
85/* These calls create a cJSON item of the appropriate type. */
86extern cJSON *cJSON_CreateNull();
87extern cJSON *cJSON_CreateTrue();
88extern cJSON *cJSON_CreateFalse();
89extern cJSON *cJSON_CreateBool(int b);
90extern cJSON *cJSON_CreateNumber(double num);
91extern cJSON *cJSON_CreateString(const char *string);
92extern cJSON *cJSON_CreateArray();
93extern cJSON *cJSON_CreateObject();
94
95/* These utilities create an Array of count items. */
96extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
97extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
98extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
99extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
100
101/* Append item to the specified array/object. */
102extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
103extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
104/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
105extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
106extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
107
108/* Remove/Detatch items from Arrays/Objects. */
109extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
110extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
111extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
112extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
113
114/* Update array items. */
115extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
116extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
117
118#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
119#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
120#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
121#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
122#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
123
124#ifdef __cplusplus
125}
126#endif
127
128#endif
diff --git a/src/include/extra/cencode.h b/src/include/extra/cencode.h
new file mode 100644
index 0000000..b001ef7
--- /dev/null
+++ b/src/include/extra/cencode.h
@@ -0,0 +1,38 @@
1/*
2cencode.h - c header for a base64 encoding algorithm
3
4This is part of the libb64 project, and has been placed in the public domain.
5For details, see http://sourceforge.net/projects/libb64
6*/
7
8#ifndef BASE64_CENCODE_H
9#define BASE64_CENCODE_H
10
11
12#ifdef HAVE_CONFIG_H
13# include "config.h"
14#endif
15
16#include <stdlib.h>
17
18typedef enum
19{
20 step_A, step_B, step_C
21} base64_encodestep;
22
23typedef struct
24{
25 base64_encodestep step;
26 char result;
27 int stepcount;
28} base64_encodestate;
29
30void base64_init_encodestate(base64_encodestate* state_in);
31
32char base64_encode_value(char value_in);
33
34int base64_encode_block(const char* plaintext_in, size_t length_in, char* code_out, base64_encodestate* state_in);
35
36int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
37
38#endif /* BASE64_CENCODE_H */
diff --git a/src/lib/skypunch_private.h b/src/include/skypunch_private.h
index 26b90fe..c0fcf2b 100644
--- a/src/lib/skypunch_private.h
+++ b/src/include/skypunch_private.h
@@ -7,7 +7,7 @@
7extern int _skypunch_log_dom_global; 7extern int _skypunch_log_dom_global;
8 8
9typedef Skypunch_Type (*Skypunch_Module_Init)(Skypunch *); 9typedef Skypunch_Type (*Skypunch_Module_Init)(Skypunch *);
10typedef Eina_Bool (*Skypunch_Module_Login)(Skypunch *); 10typedef Eina_Bool (*Skypunch_Module_Login)(void *, const char *);
11 11
12typedef struct _Skypunch_Module 12typedef struct _Skypunch_Module
13{ 13{
diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk
index b981cb0..5f25b7a 100644
--- a/src/lib/Makefile.mk
+++ b/src/lib/Makefile.mk
@@ -1,11 +1,14 @@
1LIB_CPPFLAGS= \ 1LIB_CPPFLAGS= \
2-I$(top_srcdir) \ 2-I$(top_srcdir) \
3-I$(top_srcdir)/src/include \ 3-I$(top_srcdir)/src/include \
4-I$(top_srcdir)/src/include/extra \
4-DSKYPUNCH_MODULE_PATH=\"$(libdir)/skypunch/$(MODULE_ARCH)\" 5-DSKYPUNCH_MODULE_PATH=\"$(libdir)/skypunch/$(MODULE_ARCH)\"
5 6
6noinst_LTLIBRARIES = \ 7noinst_LTLIBRARIES = \
7src/lib/libskypunch.la \ 8src/lib/libskypunch.la \
8src/lib/libaes.la 9src/lib/libaes.la \
10src/lib/libcencode.la \
11src/lib/libcjson.la
9 12
10src_lib_libskypunch_la_CFLAGS = @SKYPUNCH_CFLAGS@ 13src_lib_libskypunch_la_CFLAGS = @SKYPUNCH_CFLAGS@
11src_lib_libskypunch_la_CPPFLAGS = $(LIB_CPPFLAGS) 14src_lib_libskypunch_la_CPPFLAGS = $(LIB_CPPFLAGS)
@@ -16,7 +19,22 @@ src/lib/skypunch_main.c \
16src/lib/skypunch_private.h 19src/lib/skypunch_private.h
17 20
18src_lib_libaes_la_CFLAGS = 21src_lib_libaes_la_CFLAGS =
22src_lib_libaes_la_CPPFLAGS = $(LIB_CPPFLAGS)
19src_lib_libaes_la_LDFLAGS = 23src_lib_libaes_la_LDFLAGS =
20src_lib_libaes_la_SOURCES = \ 24src_lib_libaes_la_SOURCES = \
21src/lib/extra/aes.c \ 25src/lib/extra/aes.c \
22src/lib/extra/aes.h 26src/lib/extra/aes.h
27
28src_lib_libcencode_la_CFLAGS =
29src_lib_libcencode_la_CPPFLAGS = $(LIB_CPPFLAGS)
30src_lib_libcencode_la_LDFLAGS =
31src_lib_libcencode_la_SOURCES = \
32src/lib/extra/cencode.c \
33src/lib/extra/cencode.h
34
35src_lib_libcjson_la_CFLAGS =
36src_lib_libcjson_la_CPPFLAGS = $(LIB_CPPFLAGS)
37src_lib_libcjson_la_LDFLAGS =
38src_lib_libcjson_la_SOURCES = \
39src/lib/extra/cJSON.c \
40src/lib/extra/cJSON.h
diff --git a/src/lib/extra/cJSON.c b/src/lib/extra/cJSON.c
new file mode 100644
index 0000000..5656730
--- /dev/null
+++ b/src/lib/extra/cJSON.c
@@ -0,0 +1,524 @@
1/*
2 Copyright (c) 2009 Dave Gamble
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21*/
22
23/* cJSON */
24/* JSON parser in C. */
25
26#include <string.h>
27#include <stdio.h>
28#include <math.h>
29#include <stdlib.h>
30#include <float.h>
31#include <limits.h>
32#include <ctype.h>
33#include <cJSON.h>
34
35static const char *ep;
36
37const char *cJSON_GetErrorPtr() {return ep;}
38
39static int cJSON_strcasecmp(const char *s1,const char *s2)
40{
41 if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
42 for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
43 return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
44}
45
46static void *(*cJSON_malloc)(size_t sz) = malloc;
47static void (*cJSON_free)(void *ptr) = free;
48
49static char* cJSON_strdup(const char* str)
50{
51 size_t len;
52 char* copy;
53
54 len = strlen(str) + 1;
55 if (!(copy = (char*)cJSON_malloc(len))) return 0;
56 memcpy(copy,str,len);
57 return copy;
58}
59
60void cJSON_InitHooks(cJSON_Hooks* hooks)
61{
62 if (!hooks) { /* Reset hooks */
63 cJSON_malloc = malloc;
64 cJSON_free = free;
65 return;
66 }
67
68 cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
69 cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
70}
71
72/* Internal constructor. */
73static cJSON *cJSON_New_Item()
74{
75 cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
76 if (node) memset(node,0,sizeof(cJSON));
77 return node;
78}
79
80/* Delete a cJSON structure. */
81void cJSON_Delete(cJSON *c)
82{
83 cJSON *next;
84 while (c)
85 {
86 next=c->next;
87 if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
88 if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
89 if (c->string) cJSON_free(c->string);
90 cJSON_free(c);
91 c=next;
92 }
93}
94
95/* Parse the input text to generate a number, and populate the result into item. */
96static const char *parse_number(cJSON *item,const char *num)
97{
98 double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
99
100 /* Could use sscanf for this? */
101 if (*num=='-') sign=-1,num++; /* Has sign? */
102 if (*num=='0') num++; /* is zero */
103 if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
104 if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
105 if (*num=='e' || *num=='E') /* Exponent? */
106 { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
107 while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
108 }
109
110 n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
111
112 item->valuedouble=n;
113 item->valueint=(int)n;
114 item->type=cJSON_Number;
115 return num;
116}
117
118/* Render the number nicely from the given item into a string. */
119static char *print_number(cJSON *item)
120{
121 char *str;
122 double d=item->valuedouble;
123 if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
124 {
125 str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
126 if (str) sprintf(str,"%d",item->valueint);
127 }
128 else
129 {
130 str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
131 if (str)
132 {
133 if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d);
134 else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
135 else sprintf(str,"%f",d);
136 }
137 }
138 return str;
139}
140
141/* Parse the input text into an unescaped cstring, and populate item. */
142static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
143static const char *parse_string(cJSON *item,const char *str)
144{
145 const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
146 if (*str!='\"') {ep=str;return 0;} /* not a string! */
147
148 while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
149
150 out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
151 if (!out) return 0;
152
153 ptr=str+1;ptr2=out;
154 while (*ptr!='\"' && *ptr)
155 {
156 if (*ptr!='\\') *ptr2++=*ptr++;
157 else
158 {
159 ptr++;
160 switch (*ptr)
161 {
162 case 'b': *ptr2++='\b'; break;
163 case 'f': *ptr2++='\f'; break;
164 case 'n': *ptr2++='\n'; break;
165 case 'r': *ptr2++='\r'; break;
166 case 't': *ptr2++='\t'; break;
167 case 'u': /* transcode utf16 to utf8. */
168 sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */
169
170 if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid.
171
172 if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs.
173 {
174 if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate.
175 sscanf(ptr+3,"%4x",&uc2);ptr+=6;
176 if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate.
177 uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
178 }
179
180 len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
181
182 switch (len) {
183 case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
184 case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
185 case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
186 case 1: *--ptr2 =(uc | firstByteMark[len]);
187 }
188 ptr2+=len;
189 break;
190 default: *ptr2++=*ptr; break;
191 }
192 ptr++;
193 }
194 }
195 *ptr2=0;
196 if (*ptr=='\"') ptr++;
197 item->valuestring=out;
198 item->type=cJSON_String;
199 return ptr;
200}
201
202/* Render the cstring provided to an escaped version that can be printed. */
203static char *print_string_ptr(const char *str)
204{
205 const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
206
207 if (!str) return cJSON_strdup("");
208 ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
209
210 out=(char*)cJSON_malloc(len+3);
211 if (!out) return 0;
212
213 ptr2=out;ptr=str;
214 *ptr2++='\"';
215 while (*ptr)
216 {
217 if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
218 else
219 {
220 *ptr2++='\\';
221 switch (token=*ptr++)
222 {
223 case '\\': *ptr2++='\\'; break;
224 case '\"': *ptr2++='\"'; break;
225 case '\b': *ptr2++='b'; break;
226 case '\f': *ptr2++='f'; break;
227 case '\n': *ptr2++='n'; break;
228 case '\r': *ptr2++='r'; break;
229 case '\t': *ptr2++='t'; break;
230 default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
231 }
232 }
233 }
234 *ptr2++='\"';*ptr2++=0;
235 return out;
236}
237/* Invote print_string_ptr (which is useful) on an item. */
238static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
239
240/* Predeclare these prototypes. */
241static const char *parse_value(cJSON *item,const char *value);
242static char *print_value(cJSON *item,int depth,int fmt);
243static const char *parse_array(cJSON *item,const char *value);
244static char *print_array(cJSON *item,int depth,int fmt);
245static const char *parse_object(cJSON *item,const char *value);
246static char *print_object(cJSON *item,int depth,int fmt);
247
248/* Utility to jump whitespace and cr/lf */
249static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
250
251/* Parse an object - create a new root, and populate. */
252cJSON *cJSON_Parse(const char *value)
253{
254 cJSON *c=cJSON_New_Item();
255 ep=0;
256 if (!c) return 0; /* memory fail */
257
258 if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
259 return c;
260}
261
262/* Render a cJSON item/entity/structure to text. */
263char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
264char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
265
266/* Parser core - when encountering text, process appropriately. */
267static const char *parse_value(cJSON *item,const char *value)
268{
269 if (!value) return 0; /* Fail on null. */
270 if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
271 if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
272 if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
273 if (*value=='\"') { return parse_string(item,value); }
274 if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
275 if (*value=='[') { return parse_array(item,value); }
276 if (*value=='{') { return parse_object(item,value); }
277
278 ep=value;return 0; /* failure. */
279}
280
281/* Render a value to text. */
282static char *print_value(cJSON *item,int depth,int fmt)
283{
284 char *out=0;
285 if (!item) return 0;
286 switch ((item->type)&255)
287 {
288 case cJSON_NULL: out=cJSON_strdup("null"); break;
289 case cJSON_False: out=cJSON_strdup("false");break;
290 case cJSON_True: out=cJSON_strdup("true"); break;
291 case cJSON_Number: out=print_number(item);break;
292 case cJSON_String: out=print_string(item);break;
293 case cJSON_Array: out=print_array(item,depth,fmt);break;
294 case cJSON_Object: out=print_object(item,depth,fmt);break;
295 }
296 return out;
297}
298
299/* Build an array from input text. */
300static const char *parse_array(cJSON *item,const char *value)
301{
302 cJSON *child;
303 if (*value!='[') {ep=value;return 0;} /* not an array! */
304
305 item->type=cJSON_Array;
306 value=skip(value+1);
307 if (*value==']') return value+1; /* empty array. */
308
309 item->child=child=cJSON_New_Item();
310 if (!item->child) return 0; /* memory fail */
311 value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
312 if (!value) return 0;
313
314 while (*value==',')
315 {
316 cJSON *new_item;
317 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
318 child->next=new_item;new_item->prev=child;child=new_item;
319 value=skip(parse_value(child,skip(value+1)));
320 if (!value) return 0; /* memory fail */
321 }
322
323 if (*value==']') return value+1; /* end of array */
324 ep=value;return 0; /* malformed. */
325}
326
327/* Render an array to text */
328static char *print_array(cJSON *item,int depth,int fmt)
329{
330 char **entries;
331 char *out=0,*ptr,*ret;int len=5;
332 cJSON *child=item->child;
333 int numentries=0,i=0,j=0,fail=0;
334
335 /* How many entries in the array? */
336 while (child) numentries++,child=child->next;
337 /* Allocate an array to hold the values for each */
338 entries=(char**)cJSON_malloc(numentries*sizeof(char*));
339 if (!entries) return 0;
340 memset(entries,0,numentries*sizeof(char*));
341 /* Retrieve all the results: */
342 child=item->child;
343 while (child && !fail)
344 {
345 ret=print_value(child,depth+1,fmt);
346 entries[i++]=ret;
347 if (ret) len+=strlen(ret)+3+(fmt?depth*2:0); else fail=1;
348 child=child->next;
349 }
350
351 /* If we didn't fail, try to malloc the output string */
352 if (!fail) out=(char*)cJSON_malloc(len);
353 /* If that fails, we fail. */
354 if (!out) fail=1;
355
356 /* Handle failure. */
357 if (fail)
358 {
359 for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
360 cJSON_free(entries);
361 return 0;
362 }
363
364 /* Compose the output array. */
365 *out='[';
366 ptr=out+1;*ptr=0;
367 for (i=0;i<numentries;i++)
368 {
369 if(fmt) {
370 *ptr++='\n';
371 for (j=0; j<depth; j++) *ptr++='\t';
372 }
373 strcpy(ptr,entries[i]); ptr+=strlen(entries[i]);
374 if (i!=numentries-1) {
375 *ptr++=',';
376 *ptr=0;
377 } else if(fmt) {
378 *ptr++='\n';
379 for (j=0; j<depth; j++) *ptr++='\t';
380 }
381 cJSON_free(entries[i]);
382 }
383 cJSON_free(entries);
384 *ptr++=']';*ptr++=0;
385 return out;
386}
387
388/* Build an object from the text. */
389static const char *parse_object(cJSON *item,const char *value)
390{
391 cJSON *child;
392 if (*value!='{') {ep=value;return 0;} /* not an object! */
393
394 item->type=cJSON_Object;
395 value=skip(value+1);
396 if (*value=='}') return value+1; /* empty array. */
397
398 item->child=child=cJSON_New_Item();
399 if (!item->child) return 0;
400 value=skip(parse_string(child,skip(value)));
401 if (!value) return 0;
402 child->string=child->valuestring;child->valuestring=0;
403 if (*value!=':') {ep=value;return 0;} /* fail! */
404 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
405 if (!value) return 0;
406
407 while (*value==',')
408 {
409 cJSON *new_item;
410 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
411 child->next=new_item;new_item->prev=child;child=new_item;
412 value=skip(parse_string(child,skip(value+1)));
413 if (!value) return 0;
414 child->string=child->valuestring;child->valuestring=0;
415 if (*value!=':') {ep=value;return 0;} /* fail! */
416 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
417 if (!value) return 0;
418 }
419
420 if (*value=='}') return value+1; /* end of array */
421 ep=value;return 0; /* malformed. */
422}
423
424/* Render an object to text. */
425static char *print_object(cJSON *item,int depth,int fmt)
426{
427 char **entries=0,**names=0;
428 char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
429 cJSON *child=item->child;
430 int numentries=0,fail=0;
431 /* Count the number of entries. */
432 while (child) numentries++,child=child->next;
433 /* Allocate space for the names and the objects */
434 entries=(char**)cJSON_malloc(numentries*sizeof(char*));
435 if (!entries) return 0;
436 names=(char**)cJSON_malloc(numentries*sizeof(char*));
437 if (!names) {cJSON_free(entries);return 0;}
438 memset(entries,0,sizeof(char*)*numentries);
439 memset(names,0,sizeof(char*)*numentries);
440
441 /* Collect all the results into our arrays: */
442 child=item->child;depth++;if (fmt) len+=depth;
443 while (child)
444 {
445 names[i]=str=print_string_ptr(child->string);
446 entries[i++]=ret=print_value(child,depth,fmt);
447 if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
448 child=child->next;
449 }
450
451 /* Try to allocate the output string */
452 if (!fail) out=(char*)cJSON_malloc(len);
453 if (!out) fail=1;
454
455 /* Handle failure */
456 if (fail)
457 {
458 for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
459 cJSON_free(names);cJSON_free(entries);
460 return 0;
461 }
462
463 /* Compose the output: */
464 *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
465 for (i=0;i<numentries;i++)
466 {
467 if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
468 strcpy(ptr,names[i]);ptr+=strlen(names[i]);
469 *ptr++=':';if (fmt) *ptr++='\t';
470 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
471 if (i!=numentries-1) *ptr++=',';
472 if (fmt) *ptr++='\n';*ptr=0;
473 cJSON_free(names[i]);cJSON_free(entries[i]);
474 }
475
476 cJSON_free(names);cJSON_free(entries);
477 if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
478 *ptr++='}';*ptr++=0;
479 return out;
480}
481
482/* Get Array size/item / object item. */
483int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
484cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
485cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
486
487/* Utility for array list handling. */
488static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
489/* Utility for handling references. */
490static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
491
492/* Add item to array/object. */
493void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
494void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
495void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
496void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
497
498cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
499 if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
500void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
501cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
502void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
503
504/* Replace array/object items with new ones. */
505void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
506 newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
507 if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
508void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
509
510/* Create basic types: */
511cJSON *cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
512cJSON *cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
513cJSON *cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
514cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
515cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
516cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
517cJSON *cJSON_CreateArray() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
518cJSON *cJSON_CreateObject() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
519
520/* Create Arrays: */
521cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
522cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
523cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
524cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
diff --git a/src/lib/extra/cencode.c b/src/lib/extra/cencode.c
new file mode 100644
index 0000000..551a4f4
--- /dev/null
+++ b/src/lib/extra/cencode.c
@@ -0,0 +1,110 @@
1/*
2cencoder.c - c source to a base64 encoding algorithm implementation
3
4This is part of the libb64 project, and has been placed in the public domain.
5For details, see http://sourceforge.net/projects/libb64
6*/
7
8#include "cencode.h"
9
10const int CHARS_PER_LINE = 72;
11
12void base64_init_encodestate(base64_encodestate* state_in)
13{
14 state_in->step = step_A;
15 state_in->result = 0;
16 state_in->stepcount = 0;
17}
18
19char base64_encode_value(char value_in)
20{
21 static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
22 if (value_in > 63) return '=';
23 return encoding[(int)value_in];
24}
25
26int base64_encode_block(const char* plaintext_in, size_t length_in, char* code_out, base64_encodestate* state_in)
27{
28 const char* plainchar = plaintext_in;
29 const char* const plaintextend = plaintext_in + length_in;
30 char* codechar = code_out;
31 char result;
32 char fragment;
33
34 result = state_in->result;
35
36 switch (state_in->step)
37 {
38 while (1)
39 {
40 case step_A:
41 if (plainchar == plaintextend)
42 {
43 state_in->result = result;
44 state_in->step = step_A;
45 return codechar - code_out;
46 }
47 fragment = *plainchar++;
48 result = (fragment & 0x0fc) >> 2;
49 *codechar++ = base64_encode_value(result);
50 result = (fragment & 0x003) << 4;
51 case step_B:
52 if (plainchar == plaintextend)
53 {
54 state_in->result = result;
55 state_in->step = step_B;
56 return codechar - code_out;
57 }
58 fragment = *plainchar++;
59 result |= (fragment & 0x0f0) >> 4;
60 *codechar++ = base64_encode_value(result);
61 result = (fragment & 0x00f) << 2;
62 case step_C:
63 if (plainchar == plaintextend)
64 {
65 state_in->result = result;
66 state_in->step = step_C;
67 return codechar - code_out;
68 }
69 fragment = *plainchar++;
70 result |= (fragment & 0x0c0) >> 6;
71 *codechar++ = base64_encode_value(result);
72 result = (fragment & 0x03f) >> 0;
73 *codechar++ = base64_encode_value(result);
74/*
75 ++(state_in->stepcount);
76 if (state_in->stepcount == CHARS_PER_LINE/4)
77 {
78 *codechar++ = '\n';
79 state_in->stepcount = 0;
80 }
81*/
82 }
83 }
84 /* control should not reach here */
85 return codechar - code_out;
86}
87
88int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
89{
90 char* codechar = code_out;
91
92 switch (state_in->step)
93 {
94 case step_B:
95 *codechar++ = base64_encode_value(state_in->result);
96 *codechar++ = '=';
97 *codechar++ = '=';
98 break;
99 case step_C:
100 *codechar++ = base64_encode_value(state_in->result);
101 //*codechar++ = '=';
102 break;
103 case step_A:
104 break;
105 }
106 *codechar++ = '\n';
107
108 return codechar - code_out;
109}
110
diff --git a/src/lib/skypunch_main.c b/src/lib/skypunch_main.c
index 48bd9db..fd546cc 100644
--- a/src/lib/skypunch_main.c
+++ b/src/lib/skypunch_main.c
@@ -6,12 +6,14 @@ static int _skypunch_init_count;
6static Eina_Inlist *skypunch_modules = NULL; 6static Eina_Inlist *skypunch_modules = NULL;
7 7
8Eina_Bool 8Eina_Bool
9skypunch_login(Skypunch *skypunch) 9skypunch_login(Skypunch *skypunch, const char *auth)
10{ 10{
11 EINA_SAFETY_ON_NULL_RETURN_VAL(skypunch, EINA_FALSE); 11 EINA_SAFETY_ON_NULL_RETURN_VAL(skypunch, EINA_FALSE);
12 EINA_SAFETY_ON_NULL_RETURN_VAL(skypunch->backend.login, EINA_FALSE); 12 EINA_SAFETY_ON_NULL_RETURN_VAL(skypunch->backend.login, EINA_FALSE);
13 13
14 return skypunch->backend.login(skypunch); 14 skypunch->auth = strdup(auth);
15
16 return skypunch->backend.login(skypunch->backend.data, auth);
15} 17}
16 18
17Eina_Bool 19Eina_Bool
@@ -80,8 +82,7 @@ skypunch_type_set(Skypunch *sp,
80} 82}
81 83
82Skypunch * 84Skypunch *
83skypunch_new(Skypunch_Type type, 85skypunch_new(Skypunch_Type type)
84 const char *auth)
85{ 86{
86 Skypunch *sp; 87 Skypunch *sp;
87 88
@@ -91,8 +92,6 @@ skypunch_new(Skypunch_Type type,
91 ERR("Failed to allocate Skypunch structure."); 92 ERR("Failed to allocate Skypunch structure.");
92 return NULL; 93 return NULL;
93 } 94 }
94 sp->auth = strdup(auth);
95
96 skypunch_type_set(sp, type); 95 skypunch_type_set(sp, type);
97 return sp; 96 return sp;
98} 97}
diff --git a/src/modules/Makefile.mk b/src/modules/Makefile.mk
index 8a3fb00..1d88ad6 100644
--- a/src/modules/Makefile.mk
+++ b/src/modules/Makefile.mk
@@ -1,20 +1,24 @@
1MODULE_CPPFLAGS= \ 1MODULE_CPPFLAGS= \
2-I$(top_srcdir) \ 2-I$(top_srcdir) \
3-I$(top_srcdir)/src/include \ 3-I$(top_srcdir)/src/include \
4-I$(top_srcdir)/src/lib \ 4-I$(top_srcdir)/src/include/extra
5-I$(top_srcdir)/src/lib/extra
6 5
7moddir = $(libdir)/skypunch/$(MODULE_ARCH) 6moddir = $(libdir)/skypunch/$(MODULE_ARCH)
8mod_LTLIBRARIES = src/modules/mega.la 7mod_LTLIBRARIES = src/modules/mega.la
9 8
10src_modules_mega_la_SOURCES = \ 9src_modules_mega_la_SOURCES = \
11src/modules/mega/mega_main.c \ 10src/modules/mega/mega_main.c \
12src/modules/mega/mega_utils.c 11src/modules/mega/mega_event.c \
12src/modules/mega/mega_login.c \
13src/modules/mega/mega_utils.c \
14src/modules/mega/mega.h
13 15
14src_modules_mega_la_CFLAGS = @SKYPUNCH_CFLAGS@ 16src_modules_mega_la_CFLAGS = @SKYPUNCH_CFLAGS@
15src_modules_mega_la_LIBADD = \ 17src_modules_mega_la_LIBADD = \
16src/lib/libskypunch.la \ 18src/lib/libskypunch.la \
17src/lib/libaes.la 19src/lib/libaes.la \
20src/lib/libcencode.la \
21src/lib/libcjson.la
18src_modules_mega_la_CPPFLAGS= $(MODULE_CPPFLAGS) 22src_modules_mega_la_CPPFLAGS= $(MODULE_CPPFLAGS)
19src_modules_mega_la_LDFLAGS = \ 23src_modules_mega_la_LDFLAGS = \
20@SKYPUNCH_LIBS@ \ 24@SKYPUNCH_LIBS@ \
diff --git a/src/modules/mega/mega.h b/src/modules/mega/mega.h
index 7189725..2a9967d 100644
--- a/src/modules/mega/mega.h
+++ b/src/modules/mega/mega.h
@@ -1,8 +1,43 @@
1#include <skypunch_private.h> 1#include <skypunch_private.h>
2#include <aes.h> 2#include <aes.h>
3#include <cencode.h>
4#include <cJSON.h>
3 5
6
7typedef struct _Mega
8{
9 Skypunch *skypunch;
10 Ecore_Con_Url *ecu;
11
12 struct
13 {
14 const char *email,
15 *password;
16 } info;
17
18 struct
19 {
20 char password[16];
21 unsigned int id;
22 } session;
23
24 struct
25 {
26 Ecore_Event_Handler *ed,
27 *ec;
28 } ev;
29} Mega;
30
31Eina_Bool mega_event_data(void *data, int type, void *event_info);
32Eina_Bool mega_event_complete(void *data, int type, void *event_info);
33
34
35Eina_Bool mega_login_send(Mega *mega, const char *json);
36const char * mega_login_json(const char *email, const char *hash);
37const char * mega_login_encode(Mega *mega, const char *auth);
38
39void mega_utils_print(const char *s, int len);
40char * mega_utils_base64_encode(const unsigned char *string, size_t len, size_t *size);
4const char * mega_utils_key_encode(const char *s); 41const char * mega_utils_key_encode(const char *s);
5const char * mega_utils_login_hash(const char *email, const char *password); 42const char * mega_utils_login_hash(const char *email, const char *password);
6const char * mega_utils_login_encode(const char *auth, size_t *len);
7void mega_utils_print(const char *s, int len);
8 43
diff --git a/src/modules/mega/mega_event.c b/src/modules/mega/mega_event.c
new file mode 100644
index 0000000..e87b816
--- /dev/null
+++ b/src/modules/mega/mega_event.c
@@ -0,0 +1,25 @@
1#include "mega.h"
2
3Eina_Bool
4mega_event_data(void *data, int type, void *event_info)
5{
6 Ecore_Con_Event_Url_Data *url_data = event_info;
7 unsigned int i;
8
9 printf("Received %i bytes\n", url_data->size);
10 for (i = 0; i < url_data->size; i++)
11 printf("%c", url_data->data[i]);
12 printf("\n");
13
14 return EINA_TRUE;
15}
16
17Eina_Bool
18mega_event_complete(void *data, int type, void *event_info)
19{
20 Ecore_Con_Event_Url_Complete *url_complete = event_info;
21
22 printf("download completed with status code: %d\n", url_complete->status);
23
24 return EINA_TRUE;
25}
diff --git a/src/modules/mega/mega_login.c b/src/modules/mega/mega_login.c
new file mode 100644
index 0000000..1628b50
--- /dev/null
+++ b/src/modules/mega/mega_login.c
@@ -0,0 +1,68 @@
1#include "mega.h"
2
3#define URL "https://staging.api.mega.co.nz/"
4#define APIKEY "SDKSAMPLE"
5
6Eina_Bool
7mega_login_send(Mega *mega, const char *json)
8{
9 char *data;
10 size_t len;
11
12 len = strlen(json);
13 data = calloc(1, len + 3);
14 data[0] = '[';
15 strcpy(data+1, json);
16 data[len+1] = ']';
17
18 printf("sending %s\n", data);
19
20 mega->ecu = ecore_con_url_new(URL"cs?id=fxbkjndgmz&ak="APIKEY);
21 ecore_con_url_data_set(mega->ecu, mega);
22 ecore_con_url_post(mega->ecu, data, len+2, NULL);
23 free(data);
24 return EINA_TRUE;
25}
26
27const char *
28mega_login_json(const char *email, const char *hash)
29{
30 cJSON *json;
31 char *s;
32
33 json = cJSON_CreateObject();
34
35 cJSON_AddItemToObject(json, "a", cJSON_CreateString("us"));
36 cJSON_AddItemToObject(json, "user", cJSON_CreateString(email));
37 cJSON_AddItemToObject(json, "uh", cJSON_CreateString(hash));
38
39 s = cJSON_PrintUnformatted(json);
40 cJSON_Delete(json);
41 return s;
42}
43
44const char *
45mega_login_encode(Mega *mega, const char *auth)
46{
47 char **s;
48 const char *password_enc,
49 *hash,
50 *hashb64,
51 *json;
52 unsigned int nb;
53 size_t len;
54
55 s = eina_str_split_full(auth, ":", 2, &nb);
56 password_enc = mega_utils_key_encode(s[1]);
57 hash = mega_utils_login_hash(s[0], password_enc);
58 hashb64 = mega_utils_base64_encode(hash, 8, &len);
59 json = mega_login_json(s[0], hashb64);
60 mega->info.email = strdup(s[0]);
61 mega->info.password = strdup(s[1]);
62 strncpy(mega->session.password, password_enc, 16);
63
64 free((char *)password_enc);
65 free(s[0]);
66 free(s);
67 return json;
68}
diff --git a/src/modules/mega/mega_main.c b/src/modules/mega/mega_main.c
index 9edd4f3..757d069 100644
--- a/src/modules/mega/mega_main.c
+++ b/src/modules/mega/mega_main.c
@@ -1,18 +1,25 @@
1#include "mega.h" 1#include "mega.h"
2 2
3Eina_Bool 3Eina_Bool
4mega_login(Skypunch *skypunch) 4mega_login(Mega *mega, const char *auth)
5{ 5{
6 size_t len; 6 size_t len;
7 const char *hash; 7 const char *json;
8 8
9 EINA_SAFETY_ON_NULL_RETURN_VAL(skypunch, EINA_FALSE); 9 EINA_SAFETY_ON_NULL_RETURN_VAL(mega, EINA_FALSE);
10 EINA_SAFETY_ON_NULL_RETURN_VAL(auth, EINA_FALSE);
10 11
11 DBG("skypunch[%p]"); 12 DBG("mega[%p]", mega);
12 13
13 hash = mega_utils_login_encode(skypunch->auth, &len); 14 json = mega_login_encode(mega, auth);
15 if (!json)
16 {
17 ERR("Failed to create hash");
18 return EINA_FALSE;
19 }
14 20
15 mega_utils_print(hash, 16); 21 printf("json=\n%s\n", json);
22 mega_login_send(mega, json);
16 return EINA_TRUE; 23 return EINA_TRUE;
17} 24}
18 25
@@ -20,12 +27,29 @@ mega_login(Skypunch *skypunch)
20Skypunch_Type 27Skypunch_Type
21skypunch_module_init(Skypunch *skypunch) 28skypunch_module_init(Skypunch *skypunch)
22{ 29{
30 Mega *mega;
31
23 if (!skypunch) 32 if (!skypunch)
24 return SKYPUNCH_MEGA; 33 return SKYPUNCH_MEGA;
25 34
26 INFO("skypunch[%p] Skypunch type set to mega.co.nz"); 35 INFO("skypunch[%p] Skypunch type set to mega.co.nz");
27 36
37 ecore_con_url_init();
38
39 mega = calloc(1, sizeof(Mega));
40 mega->skypunch = skypunch;
41
28 skypunch->type = SKYPUNCH_MEGA; 42 skypunch->type = SKYPUNCH_MEGA;
29 skypunch->backend.login = mega_login; 43 skypunch->backend.data = mega;
44 skypunch->backend.login = (Skypunch_Module_Login)mega_login;
45
46#define _EV(_a, _b, _c, _d) \
47 _a = ecore_event_handler_add(ECORE_CON_EVENT_URL_##_b, mega_event_##_c, _d)
48
49 _EV(mega->ev.ed, DATA, data, mega);
50 _EV(mega->ev.ec, COMPLETE, complete, mega);
51
52#undef _EV
53
30 return SKYPUNCH_MEGA; 54 return SKYPUNCH_MEGA;
31} 55}
diff --git a/src/modules/mega/mega_utils.c b/src/modules/mega/mega_utils.c
index 7ec92ca..f6e7a61 100644
--- a/src/modules/mega/mega_utils.c
+++ b/src/modules/mega/mega_utils.c
@@ -10,6 +10,31 @@ mega_utils_print(const char *s, int len)
10 printf("\n"); 10 printf("\n");
11} 11}
12 12
13char *
14mega_utils_base64_encode(const unsigned char *string, size_t len, size_t *size)
15{
16 base64_encodestate s;
17 char *ret = NULL;
18 size_t retlen[2];
19
20 if ((len < 1) || (!string)) return NULL;
21
22 if (!(ret = malloc(sizeof(char) * ((((len + 2) - ((size_t)(len + 2) % 3)) / 3) * 4) + 4)))
23 return NULL;
24 base64_init_encodestate(&s);
25 retlen[0] = base64_encode_block((char*)string, len, ret, &s);
26 retlen[1] = base64_encode_blockend(ret + retlen[0], &s);
27 ret[retlen[0] + retlen[1]] = '\0';
28 if (ret[retlen[0] + retlen[1] - 1] == '\n')
29 {
30 ret[retlen[0] + retlen[1] - 1] = '\0';
31 *size = retlen[0] + retlen[1] - 2;
32 }
33 else
34 *size = retlen[0] + retlen[1] - 1;
35
36 return ret;
37}
13 38
14const char * 39const char *
15mega_utils_key_encode(const char *s) 40mega_utils_key_encode(const char *s)
@@ -75,23 +100,7 @@ mega_utils_login_hash(const char *email, const char *password)
75 { 100 {
76 aes_encrypt(hash, hash, key_schedule, 128); 101 aes_encrypt(hash, hash, key_schedule, 128);
77 } 102 }
78 return hash;
79}
80 103
81const char * 104 memcpy(hash+4,hash+8,4);
82mega_utils_login_encode(const char *auth, size_t *len)
83{
84 char **s;
85 const char *password_enc,
86 *hash;
87 unsigned int nb;
88
89 s = eina_str_split_full(auth, ":", 2, &nb);
90 password_enc = mega_utils_key_encode(s[1]);
91 hash = mega_utils_login_hash(s[0], password_enc);
92
93 free((char *)password_enc);
94 free(s[0]);
95 free(s);
96 return hash; 105 return hash;
97} 106}