1#include "base.h"
2
3#ifdef HAVE_LIBSMBCLIENT
4
5//#include "smb.h"
6#include "libsmbclient.h"
7#include "log.h"
8#include <net/if.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <dlinklist.h>
12#include <signal.h>
13#include <string.h>
14#include <assert.h>
15
16#ifdef USE_OPENSSL
17#include <openssl/md5.h>
18#else
19#include "md5.h"
20typedef li_MD5_CTX MD5_CTX;
21#define MD5_Init li_MD5_Init
22#define MD5_Update li_MD5_Update
23#define MD5_Final li_MD5_Final
24#endif
25
26#if EMBEDDED_EANBLE
27#ifndef APP_IPKG
28#include "disk_share.h"
29#endif
30#endif
31
32#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H)
33#include <sqlite3.h>
34#endif
35
36#define DBE 0
37#define LIGHTTPD_ARPPING_PID_FILE_PATH	"/tmp/lighttpd/lighttpd-arpping.pid"
38
39int file_exist(const char *filepath)
40{
41	struct stat stat_buf;
42    if (!stat(filepath, &stat_buf))
43    	return S_ISREG(stat_buf.st_mode);
44    else
45        return 0;
46}
47
48int dir_exist(const char *dirpath){
49	struct stat stat_buf;
50
51    if (!stat(dirpath, &stat_buf))
52    	return S_ISDIR(stat_buf.st_mode);
53    else
54    	return 0;
55}
56
57unsigned long file_size(const char *path)
58{
59    struct stat st;
60    if (stat(path, &st) == 0) return st.st_size;
61    return (unsigned long)-1;
62}
63
64char *read_whole_file(const char *target){
65	FILE *fp;
66    char *buffer, *new_str;
67    int i;
68    unsigned int read_bytes = 0;
69    unsigned int each_size = 1024;
70
71	if((fp = fopen(target, "r")) == NULL)
72    	return NULL;
73
74    buffer = (char *)malloc(sizeof(char)*each_size);
75    if(buffer == NULL){
76    	//_dprintf("No memory \"buffer\".\n");
77        fclose(fp);
78        return NULL;
79    }
80    memset(buffer, 0, each_size);
81
82    while ((i = fread(buffer+read_bytes, each_size * sizeof(char), 1, fp)) == 1){
83    	read_bytes += each_size;
84        new_str = (char *)malloc(sizeof(char)*(each_size+read_bytes));
85        if(new_str == NULL){
86        	//_dprintf("No memory \"new_str\".\n");
87            free(buffer);
88            fclose(fp);
89            return NULL;
90        }
91        memset(new_str, 0, sizeof(char)*(each_size+read_bytes));
92        memcpy(new_str, buffer, read_bytes);
93
94        free(buffer);
95        buffer = new_str;
96    }
97
98    fclose(fp);
99    return buffer;
100}
101
102char* get_aicloud_db_file_path(){
103#ifdef EMBEDDED_EANBLE
104	return "/jffs/aicloud.db";
105#else
106	return "/tmp/aicloud.db";
107#endif
108}
109
110#ifdef APP_IPKG
111/*???start?*/
112#include <dirent.h>
113#define PROTOCOL_CIFS "cifs"
114#define PROTOCOL_FTP "ftp"
115#define PROTOCOL_MEDIASERVER "dms"
116#ifdef RTCONFIG_WEBDAV_OLD
117#define PROTOCOL_WEBDAV "webdav"
118#define MAX_PROTOCOL_NUM 4
119#else
120#define MAX_PROTOCOL_NUM 3
121#endif
122
123#define PROTOCOL_CIFS_BIT 0
124#define PROTOCOL_FTP_BIT 1
125#define PROTOCOL_MEDIASERVER_BIT 2
126#ifdef RTCONFIG_WEBDAV_OLD
127#define PROTOCOL_WEBDAV_BIT 3
128#endif
129
130#define DEFAULT_SAMBA_RIGHT 3
131#define DEFAULT_FTP_RIGHT 3
132#define DEFAULT_DMS_RIGHT 1
133#ifdef RTCONFIG_WEBDAV_OLD
134#define DEFAULT_WEBDAV_RIGHT 3
135#endif
136
137#define DEBUG_USB
138
139#ifdef DEBUG_USB
140#define usb_dbg(fmt, args...) do{ \
141                FILE *fp = fopen("/tmp/usb.log", "a+"); \
142                if(fp){ \
143                        fprintf(fp, "[usb_dbg: %s] ", __FUNCTION__); \
144                        fprintf(fp, fmt, ## args); \
145                        fclose(fp); \
146                } \
147        }while(0)
148#else
149#define usb_dbg printf
150#endif
151
152/* Transfer Char to ASCII */
153int char_to_ascii_safe(const char *output, const char *input, int outsize)
154{
155	char *src = (char *)input;
156    char *dst = (char *)output;
157    char *end = (char *)output + outsize - 1;
158    char *escape = "[]"; // shouldn't be more?
159
160    if (src == NULL || dst == NULL || outsize <= 0)
161    	return 0;
162
163	for ( ; *src && dst < end; src++) {
164		if ((*src >='0' && *src <='9') ||
165            (*src >='A' && *src <='Z') ||
166            (*src >='a' && *src <='z')) {
167        	*dst++ = *src;
168        } else if (strchr(escape, *src)) {
169        	if (dst + 2 > end)
170            	break;
171            *dst++ = '\\';
172            *dst++ = *src;
173        } else {
174        	if (dst + 3 > end)
175            	break;
176            dst += sprintf(dst, "%%%.02X", *src);
177        }
178	}
179    if (dst <= end)
180    	*dst = '\0';
181
182    return dst - output;
183}
184
185#if 0
186int
187check_if_file_exist(const char *filepath)
188{
189	struct stat stat_buf;
190
191    if (!stat(filepath, &stat_buf))
192    	return S_ISREG(stat_buf.st_mode);
193    else
194        return 0;
195}
196unsigned long f_size(const char *path)	// 4GB-1	-1 = error
197{
198    struct stat st;
199    if (stat(path, &st) == 0) return st.st_size;
200    return (unsigned long)-1;
201}
202#endif
203
204extern int check_file_integrity(const char *const file_name){
205    unsigned long fsize;
206    char test_file[PATH_MAX];
207
208    if((fsize = file_size(file_name)) == -1){
209        usb_dbg("Fail to get the size of the file.\n");
210        return 0;
211    }
212
213    memset(test_file, 0, PATH_MAX);
214    sprintf(test_file, "%s.%lu", file_name, fsize);
215    if(!file_exist(test_file)){
216        usb_dbg("Fail to check the folder list.\n");
217        return 0;
218    }
219
220    return 1;
221}
222
223#if 0
224int
225check_if_dir_exist(const char *dirpath){
226	struct stat stat_buf;
227
228    if (!stat(dirpath, &stat_buf))
229    	return S_ISDIR(stat_buf.st_mode);
230    else
231    	return 0;
232}
233#endif
234
235extern int delete_file_or_dir(char *target){
236	int ret;
237
238    if(dir_exist(target))
239    	ret = rmdir(target);
240    else
241        ret = unlink(target);
242
243    return ret;
244}
245
246extern char *get_upper_str(const char *const str, char **target){
247	int len, i;
248    char *ptr;
249
250    len = strlen(str);
251    *target = (char *)malloc(sizeof(char)*(len+1));
252    if(*target == NULL){
253    	printf("No memory \"*target\".\n");
254        return NULL;
255    }
256    ptr = *target;
257    for(i = 0; i < len; ++i)
258    	ptr[i] = toupper(str[i]);
259   	ptr[len] = 0;
260
261    return ptr;
262}
263
264extern int upper_strcmp(const char *const str1, const char *const str2){
265    char *upper_str1, *upper_str2;
266    int ret;
267
268    if(str1 == NULL || str2 == NULL)
269    	return -1;
270
271    if(get_upper_str(str1, &upper_str1) == NULL)
272        return -1;
273
274    if(get_upper_str(str2, &upper_str2) == NULL){
275    	free(upper_str1);
276        return -1;
277    }
278
279    ret = strcmp(upper_str1, upper_str2);
280    free(upper_str1);
281    free(upper_str2);
282
283    return ret;
284}
285
286extern int test_if_System_folder(const char *const dirname){
287	const char *const MS_System_folder[] = {"SYSTEM VOLUME INFORMATION", "RECYCLER", "RECYCLED", "$RECYCLE.BIN", NULL};
288    const char *const Linux_System_folder[] = {"lost+found", NULL};
289    int i;
290
291    for(i = 0; MS_System_folder[i] != NULL; ++i){
292    	if(!upper_strcmp(dirname, MS_System_folder[i]))
293        	return 1;
294    }
295
296    for(i = 0; Linux_System_folder[i] != NULL; ++i){
297    	if(!upper_strcmp(dirname, Linux_System_folder[i]))
298        	return 1;
299    }
300
301    return 0;
302}
303
304extern int get_var_file_name(const char *const account, const char *const path, char **file_name){
305    int len;
306    char *var_file;
307    char ascii_user[64];
308
309    if(path == NULL)
310        return -1;
311
312    len = strlen(path)+strlen("/.___var.txt");
313    if(account != NULL){
314        memset(ascii_user, 0, 64);
315        char_to_ascii_safe(ascii_user, account, 64);
316
317        len += strlen(ascii_user);
318    }
319    *file_name = (char *)malloc(sizeof(char)*(len+1));
320    if(*file_name == NULL)
321        return -1;
322
323    var_file = *file_name;
324    if(account != NULL)
325        sprintf(var_file, "%s/.__%s_var.txt", path, ascii_user);
326    else
327        sprintf(var_file, "%s/.___var.txt", path);
328    var_file[len] = 0;
329
330    return 0;
331}
332
333
334extern char *upper_strstr(const char *const str, const char *const target){
335    char *upper_str, *upper_target;
336    char *ret;
337    int len;
338
339    if(str == NULL || target == NULL)
340    	return NULL;
341
342    if(get_upper_str(str, &upper_str) == NULL)
343    	return NULL;
344
345    if(get_upper_str(target, &upper_target) == NULL){
346    	free(upper_str);
347        return NULL;
348    }
349
350    ret = strstr(upper_str, upper_target);
351    if(ret == NULL){
352    	free(upper_str);
353        free(upper_target);
354        return NULL;
355    }
356
357    if((len = upper_str-ret) < 0)
358    	len = ret-upper_str;
359
360    free(upper_str);
361    free(upper_target);
362
363    return (char *)(str+len);
364}
365
366extern void free_2_dimension_list(int *num, char ***list) {
367    int i;
368    char **target = *list;
369
370    if (*num <= 0 || target == NULL){
371        *num = 0;
372        return;
373    }
374
375    for (i = 0; i < *num; ++i)
376        if (target[i] != NULL)
377            free(target[i]);
378
379    if (target != NULL)
380        free(target);
381
382    *num = 0;
383}
384
385extern int get_all_folder(const char *const mount_path, int *sh_num, char ***folder_list) {
386    DIR *pool_to_open;
387    struct dirent *dp;
388    char *testdir;
389    char **tmp_folder_list, **tmp_folder;
390    int len, i;
391
392    pool_to_open = opendir(mount_path);
393    if (pool_to_open == NULL) {
394        usb_dbg("Can't opendir \"%s\".\n", mount_path);
395        return -1;
396    }
397
398    *sh_num = 0;
399    while ((dp = readdir(pool_to_open)) != NULL) {
400        if (dp->d_name[0] == '.')
401            continue;
402
403        if (test_if_System_folder(dp->d_name) == 1)
404            continue;
405
406        len = strlen(mount_path)+strlen("/")+strlen(dp->d_name);
407        testdir = (char *)malloc(sizeof(char)*(len+1));
408        if (testdir == NULL) {
409            closedir(pool_to_open);
410            return -1;
411        }
412        sprintf(testdir, "%s/%s", mount_path, dp->d_name);
413        testdir[len] = 0;
414        if (!dir_exist(testdir)) {
415            free(testdir);
416            continue;
417        }
418        free(testdir);
419
420        tmp_folder = (char **)malloc(sizeof(char *)*(*sh_num+1));
421        if (tmp_folder == NULL) {
422            usb_dbg("Can't malloc \"tmp_folder\".\n");
423            return -1;
424        }
425
426        len = strlen(dp->d_name);
427        tmp_folder[*sh_num] = (char *)malloc(sizeof(char)*(len+1));
428        if (tmp_folder[*sh_num] == NULL) {
429            usb_dbg("Can't malloc \"tmp_folder[%d]\".\n", *sh_num);
430            free(tmp_folder);
431            return -1;
432        }
433        strcpy(tmp_folder[*sh_num], dp->d_name);
434        if (*sh_num != 0) {
435            for (i = 0; i < *sh_num; ++i)
436                tmp_folder[i] = tmp_folder_list[i];
437
438            free(tmp_folder_list);
439            tmp_folder_list = tmp_folder;
440        }
441        else
442            tmp_folder_list = tmp_folder;
443
444        ++(*sh_num);
445    }
446    closedir(pool_to_open);
447
448    *folder_list = tmp_folder_list;
449
450    return 0;
451}
452
453extern void set_file_integrity(const char *const file_name){
454    unsigned long fsize;
455    char test_file[PATH_MAX], test_file_name[PATH_MAX];
456    FILE *fp;
457    char target_dir[PATH_MAX], *ptr;
458    int len;
459    DIR *opened_dir;
460    struct dirent *dp;
461
462    if((ptr = strrchr(file_name, '/')) == NULL){
463        usb_dbg("Fail to get the target_dir of the file.\n");
464        return;
465    }
466    len = strlen(file_name)-strlen(ptr);
467    memset(target_dir, 0, PATH_MAX);
468    strncpy(target_dir, file_name, len);
469
470    if((fsize = file_size(file_name)) == -1){
471        usb_dbg("Fail to get the size of the file.\n");
472        return;
473    }
474
475    memset(test_file, 0, PATH_MAX);
476    sprintf(test_file, "%s.%lu", file_name, fsize);
477    if((fp = fopen(test_file, "w")) != NULL)
478        fclose(fp);
479
480    memset(test_file_name, 0, PATH_MAX);
481    ++ptr;
482    sprintf(test_file_name, "%s.%lu", ptr, fsize);
483
484    if((opened_dir = opendir(target_dir)) == NULL){
485        usb_dbg("Can't opendir \"%s\".\n", target_dir);
486        return;
487    }
488
489    len = strlen(ptr);
490    while((dp = readdir(opened_dir)) != NULL){
491        char test_path[PATH_MAX];
492
493        if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
494            continue;
495
496        if(strncmp(dp->d_name, ptr, len) || !strcmp(dp->d_name, ptr) || !strcmp(dp->d_name, test_file_name))
497            continue;
498
499        memset(test_path, 0, PATH_MAX);
500        sprintf(test_path, "%s/%s", target_dir, dp->d_name);
501        usb_dbg("delete %s.\n", test_path);
502        delete_file_or_dir(test_path);
503    }
504    closedir(opened_dir);
505}
506
507extern int initial_var_file(const char *const account, const char *const mount_path) {
508    FILE *fp;
509    char *var_file;
510    int result, i;
511    int sh_num;
512    char **folder_list;
513    int samba_right, ftp_right, dms_right;
514#ifdef RTCONFIG_WEBDAV_OLD
515    int webdav_right;
516#endif
517
518    if (mount_path == NULL || strlen(mount_path) <= 0) {
519        usb_dbg("No input, mount_path\n");
520        return -1;
521    }
522
523    // 1. get the folder number and folder_list
524    //result = get_folder_list(mount_path, &sh_num, &folder_list);
525    result = get_all_folder(mount_path, &sh_num, &folder_list);
526
527    // 2. get the var file
528    if(get_var_file_name(account, mount_path, &var_file)){
529        usb_dbg("Can't malloc \"var_file\".\n");
530        free_2_dimension_list(&sh_num, &folder_list);
531        return -1;
532    }
533
534    // 3. get the default permission of all protocol.
535    char *aa=nvram_safe_get("http_username"); //add by zero
536
537    if(account == NULL // share mode.
538       || !strcmp(account, aa)){
539//       || !strcmp(account, nvram_safe_get("http_username"))){
540        samba_right = DEFAULT_SAMBA_RIGHT;
541        ftp_right = DEFAULT_FTP_RIGHT;
542        dms_right = DEFAULT_DMS_RIGHT;
543#ifdef RTCONFIG_WEBDAV_OLD
544        webdav_right = DEFAULT_WEBDAV_RIGHT;
545#endif
546    }
547    else{
548        samba_right = 0;
549        ftp_right = 0;
550        dms_right = 0;
551#ifdef RTCONFIG_WEBDAV_OLD
552        webdav_right = 0;
553#endif
554    }
555    free(aa);
556    // 4. write the default content in the var file
557    if ((fp = fopen(var_file, "w")) == NULL) {
558        usb_dbg("Can't create the var file, \"%s\".\n", var_file);
559        free_2_dimension_list(&sh_num, &folder_list);
560        free(var_file);
561        return -1;
562    }
563
564    for (i = -1; i < sh_num; ++i) {
565        fprintf(fp, "*");
566
567        if(i != -1)
568            fprintf(fp, "%s", folder_list[i]);
569#ifdef RTCONFIG_WEBDAV_OLD
570        fprintf(fp, "=%d%d%d%d\n", samba_right, ftp_right, dms_right, webdav_right);
571#else
572        fprintf(fp, "=%d%d%d\n", samba_right, ftp_right, dms_right);
573#endif
574    }
575
576    fclose(fp);
577    free_2_dimension_list(&sh_num, &folder_list);
578
579    // 5. set the check target of file.
580    set_file_integrity(var_file);
581    free(var_file);
582
583    return 0;
584}
585
586extern int get_permission(const char *const account,
587                              const char *const mount_path,
588                              const char *const folder,
589                              const char *const protocol) {
590    char *var_file, *var_info;
591    char *target, *follow_info;
592    int len, result;
593
594    // 1. get the var file
595    if(get_var_file_name(account, mount_path, &var_file)){
596    	usb_dbg("Can't malloc \"var_file\".\n");
597        return -1;
598    }
599
600    // 2. check the file integrity.
601    if(!check_file_integrity(var_file)){
602        usb_dbg("Fail to check the file: %s.\n", var_file);
603    	if(initial_var_file(account, mount_path) != 0){
604        	usb_dbg("Can't initial \"%s\"'s file in %s.\n", account, mount_path);
605                free(var_file);
606                return -1;
607        }
608    }
609
610    // 3. get the content of the var_file of the account
611    var_info = read_whole_file(var_file);
612    if (var_info == NULL) {
613    	usb_dbg("get_permission: \"%s\" isn't existed or there's no content.\n", var_file);
614        free(var_file);
615    	return -1;
616    }
617    free(var_file);
618
619    // 4. get the target in the content
620    if(folder == NULL)
621    	len = strlen("*=");
622    else
623        len = strlen("*")+strlen(folder)+strlen("=");
624    target = (char *)malloc(sizeof(char)*(len+1));
625    if (target == NULL) {
626    	usb_dbg("Can't allocate \"target\".\n");
627        free(var_info);
628        return -1;
629    }
630    if(folder == NULL)
631    	strcpy(target, "*=");
632    else
633    	sprintf(target, "*%s=", folder);
634    target[len] = 0;
635
636    follow_info = upper_strstr(var_info, target);
637    free(target);
638    if (follow_info == NULL) {
639    	if(account == NULL)
640        	usb_dbg("No right about \"%s\" with the share mode.\n", (folder == NULL?"Pool":folder));
641        else
642        	usb_dbg("No right about \"%s\" with \"%s\".\n", (folder == NULL?"Pool":folder), account);
643        free(var_info);
644        return -1;
645	}
646
647    follow_info += len;
648
649    if (follow_info[MAX_PROTOCOL_NUM] != '\n') {
650    	if(account == NULL)
651        	usb_dbg("The var info is incorrect.\nPlease reset the var file of the share mode.\n");
652        else
653            usb_dbg("The var info is incorrect.\nPlease reset the var file of \"%s\".\n", account);
654
655        free(var_info);
656        return -1;
657    }
658
659    // 5. get the right of folder
660    if (!strcmp(protocol, PROTOCOL_CIFS))
661    	result = follow_info[0]-'0';
662    else if (!strcmp(protocol, PROTOCOL_FTP))
663        result = follow_info[1]-'0';
664    else if (!strcmp(protocol, PROTOCOL_MEDIASERVER))
665        result = follow_info[2]-'0';
666#ifdef RTCONFIG_WEBDAV_OLD
667    else if (!strcmp(protocol, PROTOCOL_WEBDAV))
668        result = follow_info[3]-'0';
669#endif
670    else{
671        usb_dbg("The protocol, \"%s\", is incorrect.\n", protocol);
672        free(var_info);
673    	return -1;
674    }
675    free(var_info);
676
677    if (result < 0 || result > 3) {
678    	if(account == NULL)
679        	usb_dbg("The var info is incorrect.\nPlease reset the var file of the share mode.\n");
680        else
681        	usb_dbg("The var info is incorrect.\nPlease reset the var file of \"%s\".\n", account);
682    	return -1;
683    }
684
685    return result;
686}
687
688/*???end?*/
689
690/*pids*/
691#include <errno.h>
692#include<sys/types.h>
693#include <dirent.h>
694#include <ctype.h>
695#include <stddef.h>
696enum {
697	PSSCAN_PID      = 1 << 0,
698    PSSCAN_PPID     = 1 << 1,
699    PSSCAN_PGID     = 1 << 2,
700    PSSCAN_SID      = 1 << 3,
701    PSSCAN_UIDGID   = 1 << 4,
702    PSSCAN_COMM     = 1 << 5,
703    /* PSSCAN_CMD      = 1 << 6, - use read_cmdline instead */
704    PSSCAN_ARGV0    = 1 << 7,
705    /* PSSCAN_EXE      = 1 << 8, - not implemented */
706    PSSCAN_STATE    = 1 << 9,
707    PSSCAN_VSZ      = 1 << 10,
708    PSSCAN_RSS      = 1 << 11,
709    PSSCAN_STIME    = 1 << 12,
710    PSSCAN_UTIME    = 1 << 13,
711    PSSCAN_TTY      = 1 << 14,
712    PSSCAN_SMAPS    = (1 << 15) * 0,
713    PSSCAN_ARGVN    = (1 << 16) * 1,
714    PSSCAN_START_TIME = 1 << 18,
715    /* These are all retrieved from proc/NN/stat in one go: */
716    PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
717                      | PSSCAN_COMM | PSSCAN_STATE
718                      | PSSCAN_VSZ | PSSCAN_RSS
719                      | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
720                      | PSSCAN_TTY,
721};
722
723#define PROCPS_BUFSIZE 1024
724
725static int read_to_buf(const char *filename, void *buf)
726{
727    int fd;
728    /* open_read_close() would do two reads, checking for EOF.
729         * When you have 10000 /proc/$NUM/stat to read, it isn't desirable */
730	int ret = -1;
731    fd = open(filename, O_RDONLY);
732   	if (fd >= 0) {
733    	ret = read(fd, buf, PROCPS_BUFSIZE-1);
734        close(fd);
735    }
736    ((char *)buf)[ret > 0 ? ret : 0] = '\0';
737    return ret;
738}
739
740void* xzalloc(size_t size)
741{
742    void *ptr = malloc(size);
743    memset(ptr, 0, size);
744    return ptr;
745}
746
747void* xrealloc(void *ptr, size_t size)
748{
749    ptr = realloc(ptr, size);
750    if (ptr == NULL && size != 0)
751    	perror("no memory");
752    return ptr;
753}
754
755void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx)
756{
757    int mask = 1 << (unsigned char)sizeof_and_shift;
758
759    if (!(idx & (mask - 1))) {
760    	sizeof_and_shift >>= 8; /* sizeof(vector[0]) */
761        vector = xrealloc(vector, sizeof_and_shift * (idx + mask + 1));
762        memset((char*)vector + (sizeof_and_shift * idx), 0, sizeof_and_shift * (mask + 1));
763    }
764    return vector;
765}
766
767#define xrealloc_vector(vector, shift, idx) \
768        xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
769
770typedef struct procps_status_t {
771    DIR *dir;
772    unsigned char shift_pages_to_bytes;
773    unsigned char shift_pages_to_kb;
774	/* Fields are set to 0/NULL if failed to determine (or not requested) */
775    unsigned int argv_len;
776    char *argv0;
777    /* Everything below must contain no ptrs to malloc'ed data:
778         * it is memset(0) for each process in procps_scan() */
779    unsigned long vsz, rss; /* we round it to kbytes */
780    unsigned long stime, utime;
781    unsigned long start_time;
782    unsigned pid;
783    unsigned ppid;
784    unsigned pgid;
785    unsigned sid;
786    unsigned uid;
787    unsigned gid;
788    unsigned tty_major,tty_minor;
789    char state[4];
790    /* basename of executable in exec(2), read from /proc/N/stat
791         * (if executable is symlink or script, it is NOT replaced
792         * by link target or interpreter name) */
793    char comm[16];
794    /* user/group? - use passwd/group parsing functions */
795} procps_status_t;
796
797static procps_status_t* alloc_procps_scan(void)
798{
799	unsigned n = getpagesize();
800    procps_status_t* sp = xzalloc(sizeof(procps_status_t));
801    sp->dir = opendir("/proc");
802    while (1) {
803    	n >>= 1;
804        if (!n) break;
805        sp->shift_pages_to_bytes++;
806    }
807    sp->shift_pages_to_kb = sp->shift_pages_to_bytes - 10;
808    return sp;
809}
810
811void BUG_comm_size(void)
812{
813}
814#define ULLONG_MAX     (~0ULL)
815#define UINT_MAX       (~0U)
816
817static unsigned long long ret_ERANGE(void)
818{
819    errno = ERANGE; /* this ain't as small as it looks (on glibc) */
820	return ULLONG_MAX;
821}
822static unsigned long long handle_errors(unsigned long long v, char **endp, char *endptr)
823{
824    if (endp) *endp = endptr;
825
826    /* errno is already set to ERANGE by strtoXXX if value overflowed */
827    if (endptr[0]) {
828        /* "1234abcg" or out-of-range? */
829        if (isalnum(endptr[0]) || errno)
830            return ret_ERANGE();
831        /* good number, just suspicious terminator */
832        errno = EINVAL;
833    }
834    return v;
835}
836unsigned bb_strtou(const char *arg, char **endp, int base)
837{
838    unsigned long v;
839    char *endptr;
840
841    if (!isalnum(arg[0])) return ret_ERANGE();
842    errno = 0;
843    v = strtoul(arg, &endptr, base);
844    if (v > UINT_MAX) return ret_ERANGE();
845    return handle_errors(v, endp, endptr);
846}
847
848const char* bb_basename(const char *name)
849{
850    const char *cp = strrchr(name, '/');
851    if (cp)
852    	return cp + 1;
853    return name;
854}
855
856static int comm_match(procps_status_t *p, const char *procName)
857{
858    int argv1idx;
859
860    /* comm does not match */
861    if (strncmp(p->comm, procName, 15) != 0)
862    	return 0;
863
864    /* in Linux, if comm is 15 chars, it may be a truncated */
865    if (p->comm[14] == '\0') /* comm is not truncated - match */
866         return 1;
867
868    /* comm is truncated, but first 15 chars match.
869         * This can be crazily_long_script_name.sh!
870         * The telltale sign is basename(argv[1]) == procName. */
871
872    if (!p->argv0)
873    	return 0;
874
875    argv1idx = strlen(p->argv0) + 1;
876    if (argv1idx >= p->argv_len)
877    	return 0;
878
879    if (strcmp(bb_basename(p->argv0 + argv1idx), procName) != 0)
880    	return 0;
881
882    return 1;
883}
884
885void free_procps_scan(procps_status_t* sp)
886{
887    closedir(sp->dir);
888    free(sp->argv0);
889    free(sp);
890}
891
892procps_status_t* procps_scan(procps_status_t* sp, int flags)
893{
894	struct dirent *entry;
895    char buf[PROCPS_BUFSIZE];
896    char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
897    char *filename_tail;
898    long tasknice;
899    unsigned pid;
900    int n;
901    struct stat sb;
902
903    if (!sp)
904    	sp = alloc_procps_scan();
905
906    for (;;) {
907    	entry = readdir(sp->dir);
908        if (entry == NULL) {
909        	free_procps_scan(sp);
910            return NULL;
911        }
912        pid = bb_strtou(entry->d_name, NULL, 10);
913        if (errno)
914        	continue;
915
916        /* After this point we have to break, not continue
917                 * ("continue" would mean that current /proc/NNN
918                 * is not a valid process info) */
919
920        memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz));
921
922        sp->pid = pid;
923        if (!(flags & ~PSSCAN_PID)) break;
924
925        filename_tail = filename + sprintf(filename, "/proc/%d", pid);
926
927        if (flags & PSSCAN_UIDGID) {
928        	if (stat(filename, &sb))
929            	break;
930        	/* Need comment - is this effective or real UID/GID? */
931            sp->uid = sb.st_uid;
932            sp->gid = sb.st_gid;
933        }
934
935        if (flags & PSSCAN_STAT) {
936        	char *cp, *comm1;
937            int tty;
938            unsigned long vsz, rss;
939
940            /* see proc(5) for some details on this */
941            strcpy(filename_tail, "/stat");
942            n = read_to_buf(filename, buf);
943            if (n < 0)
944            	break;
945            cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
946            /*if (!cp || cp[1] != ' ')
947                    	break;*/
948            cp[0] = '\0';
949            if (sizeof(sp->comm) < 16)
950            	BUG_comm_size();
951            comm1 = strchr(buf, '(');
952            /*if (comm1)*/
953            strncpy(sp->comm, comm1 + 1, sizeof(sp->comm));
954
955            n = sscanf( cp+2,
956                        "%c %u "               /* state, ppid */
957                        "%u %u %d %*s "        /* pgid, sid, tty, tpgid */
958                        "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
959                        "%lu %lu "             /* utime, stime */
960                        "%*s %*s %*s "         /* cutime, cstime, priority */
961                        "%ld "                 /* nice */
962                        "%*s %*s "             /* timeout, it_real_value */
963                        "%lu "                 /* start_time */
964                        "%lu "                 /* vsize */
965                        "%lu "                 /* rss */
966            			/*	"%lu %lu %lu %lu %lu %lu " rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
967            			/*	"%u %u %u %u "         signal, blocked, sigignore, sigcatch */
968            			/*	"%lu %lu %lu"          wchan, nswap, cnswap */
969                        ,
970                        sp->state, &sp->ppid,
971                        &sp->pgid, &sp->sid, &tty,
972                        &sp->utime, &sp->stime,
973                        &tasknice,
974                        &sp->start_time,
975                        &vsz,
976                        &rss);
977			if (n != 11)
978            	break;
979            /* vsz is in bytes and we want kb */
980            sp->vsz = vsz >> 10;
981            /* vsz is in bytes but rss is in *PAGES*! Can you believe that? */
982            sp->rss = rss << sp->shift_pages_to_kb;
983            sp->tty_major = (tty >> 8) & 0xfff;
984            sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00);
985
986            if (sp->vsz == 0 && sp->state[0] != 'Z')
987            	sp->state[1] = 'W';
988            else
989            	sp->state[1] = ' ';
990            if (tasknice < 0)
991            	sp->state[2] = '<';
992            else if (tasknice) /* > 0 */
993            	sp->state[2] = 'N';
994            else
995            	sp->state[2] = ' ';
996
997		}
998
999        if (flags & (PSSCAN_ARGV0|PSSCAN_ARGVN)) {
1000        	free(sp->argv0);
1001            sp->argv0 = NULL;
1002            strcpy(filename_tail, "/cmdline");
1003            n = read_to_buf(filename, buf);
1004            if (n <= 0)
1005            	break;
1006            if (flags & PSSCAN_ARGVN) {
1007            	sp->argv_len = n;
1008                sp->argv0 = malloc(n + 1);
1009                memcpy(sp->argv0, buf, n + 1);
1010                /* sp->argv0[n] = '\0'; - buf has it */
1011            } else {
1012            	sp->argv_len = 0;
1013                sp->argv0 = strdup(buf);
1014            }
1015        }
1016        break;
1017	}
1018    return sp;
1019}
1020
1021pid_t* find_pid_by_name(const char *procName)
1022{
1023    pid_t* pidList;
1024    int i = 0;
1025    procps_status_t* p = NULL;
1026
1027    pidList = xzalloc(sizeof(*pidList));
1028    while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN))) {
1029    	if (comm_match(p, procName)
1030        	/* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
1031            || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
1032            /* TOOD: we can also try /proc/NUM/exe link, do we want that? */
1033            ) {
1034            	if (p->state[0] != 'Z')
1035                {
1036                	pidList = xrealloc_vector(pidList, 2, i);
1037                    pidList[i++] = p->pid;
1038                }
1039    	}
1040    }
1041
1042    pidList[i] = 0;
1043    return pidList;
1044}
1045
1046int pids(char *appname)
1047{
1048    pid_t *pidList;
1049    pid_t *pl;
1050    int count = 0;
1051
1052    pidList = find_pid_by_name(appname);
1053    for (pl = pidList; *pl; pl++) {
1054    	count++;
1055    }
1056    free(pidList);
1057
1058	if (count)
1059    	return 1;
1060   	else
1061    	return 0;
1062}
1063/*pids end*/
1064
1065/*end #ifdef APP_IPKG*/
1066#endif
1067
1068const char base64_pad = '=';
1069
1070/* "A-Z a-z 0-9 + /" maps to 0-63 */
1071const short base64_reverse_table[256] = {
1072/*	 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
1073	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 - 0x0F */
1074	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 - 0x1F */
1075	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 - 0x2F */
1076	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 - 0x3F */
1077	-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 0x40 - 0x4F */
1078	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 - 0x5F */
1079	-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 - 0x6F */
1080	41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70 - 0x7F */
1081	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 - 0x8F */
1082	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 - 0x9F */
1083	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 - 0xAF */
1084	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 - 0xBF */
1085	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 - 0xCF */
1086	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 - 0xDF */
1087	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 - 0xEF */
1088	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xF0 - 0xFF */
1089};
1090
1091unsigned char * base64_decode(buffer *out, const char *in) {
1092        unsigned char *result;
1093        unsigned int j = 0; /* current output character (position) that is decoded. can contain partial result */
1094        unsigned int group = 0; /* how many base64 digits in the current group were decoded already. each group has up to 4 digits */
1095        size_t i;
1096
1097        size_t in_len = strlen(in);
1098
1099        buffer_string_prepare_copy(out, in_len);
1100
1101        result = (unsigned char *)out->ptr;
1102
1103        /* run through the whole string, converting as we go */
1104        for (i = 0; i < in_len; i++) {
1105                unsigned char c = (unsigned char) in[i];
1106                short ch;
1107
1108                if (c == '\0') break;
1109
1110                if (c == base64_pad) {
1111                        /* pad character can only come after 2 base64 digits in a group */
1112                        if (group < 2) return NULL;
1113                        break;
1114                }
1115
1116                ch = base64_reverse_table[c];
1117                if (ch < 0) continue; /* skip invalid characters */
1118
1119                switch(group) {
1120                case 0:
1121                        result[j] = ch << 2;
1122                        group = 1;
1123                        break;
1124                case 1:
1125                        result[j++] |= ch >> 4;
1126                        result[j] = (ch & 0x0f) << 4;
1127                        group = 2;
1128                        break;
1129                case 2:
1130                        result[j++] |= ch >>2;
1131                        result[j] = (ch & 0x03) << 6;
1132                        group = 3;
1133                        break;
1134                case 3:
1135                        result[j++] |= ch;
1136                        group = 0;
1137                        break;
1138                }
1139        }
1140
1141        switch(group) {
1142        case 0:
1143                /* ended on boundary */
1144                break;
1145        case 1:
1146                /* need at least 2 base64 digits per group */
1147                return NULL;
1148        case 2:
1149                /* have 2 base64 digits in last group => one real octect, two zeroes padded */
1150        case 3:
1151                /* have 3 base64 digits in last group => two real octects, one zero padded */
1152
1153                /* for both cases the current index already is on the first zero padded octet
1154                 * - check it really is zero (overlapping bits) */
1155                if (0 != result[j]) return NULL;
1156                break;
1157        }
1158
1159        result[j] = '\0';
1160        out->used = j;
1161
1162        return result;
1163}
1164//unsigned char * base64_decode(buffer *out, const char *in) {
1165//	unsigned char *result;
1166//	int ch, j = 0, k;
1167//	size_t i;
1168
1169//	size_t in_len = strlen(in);
1170
1171//	buffer_prepare_copy(out, in_len);
1172
1173//	result = (unsigned char *)out->ptr;
1174
1175//	ch = in[0];
1176//	/* run through the whole string, converting as we go */
1177//	for (i = 0; i < in_len; i++) {
1178//		ch = in[i];
1179
1180//		if (ch == '\0') break;
1181
1182//		if (ch == base64_pad) break;
1183
1184//		ch = base64_reverse_table[ch];
1185//		if (ch < 0) continue;
1186
1187//		switch(i % 4) {
1188//		case 0:
1189//			result[j] = ch << 2;
1190//			break;
1191//		case 1:
1192//			result[j++] |= ch >> 4;
1193//			result[j] = (ch & 0x0f) << 4;
1194//			break;
1195//		case 2:
1196//			result[j++] |= ch >>2;
1197//			result[j] = (ch & 0x03) << 6;
1198//			break;
1199//		case 3:
1200//			result[j++] |= ch;
1201//			break;
1202//		}
1203//	}
1204//	k = j;
1205//	/* mop things up if we ended on a boundary */
1206//	if (ch == base64_pad) {
1207//		switch(i % 4) {
1208//		case 0:
1209//		case 1:
1210//			return NULL;
1211//		case 2:
1212//			k++;
1213//		case 3:
1214//			result[k++] = 0;
1215//		}
1216//	}
1217//	result[k] = '\0';
1218
1219//	out->used = k;
1220
1221//	return result;
1222//}
1223
1224char *ldb_base64_encode(const char *buf, int len)
1225{
1226	const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1227	int bit_offset, byte_offset, idx, i;
1228	const uint8_t *d = (const uint8_t *)buf;
1229	int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
1230	char *out;
1231
1232	out = (char *)calloc(1, bytes+pad_bytes+1);
1233	if (!out) return NULL;
1234
1235	for (i=0;i<bytes;i++) {
1236		byte_offset = (i*6)/8;
1237		bit_offset = (i*6)%8;
1238		if (bit_offset < 3) {
1239			idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F;
1240		} else {
1241			idx = (d[byte_offset] << (bit_offset-2)) & 0x3F;
1242			if (byte_offset+1 < len) {
1243				idx |= (d[byte_offset+1] >> (8-(bit_offset-2)));
1244			}
1245		}
1246		out[i] = b64[idx];
1247	}
1248
1249	for (;i<bytes+pad_bytes;i++)
1250		out[i] = '=';
1251	out[i] = 0;
1252
1253	return out;
1254}
1255
1256char* get_mac_address(const char* iface, char* mac){
1257	int fd;
1258    struct ifreq ifr;
1259    fd = socket(AF_INET, SOCK_DGRAM, 0);
1260	ifr.ifr_addr.sa_family = AF_INET;
1261    strncpy(ifr.ifr_name, iface, IFNAMSIZ-1);
1262    ioctl(fd, SIOCGIFHWADDR, &ifr);
1263	close(fd);
1264    sprintf(mac,"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1265       		(unsigned char)ifr.ifr_hwaddr.sa_data[0],
1266         	(unsigned char)ifr.ifr_hwaddr.sa_data[1],
1267         	(unsigned char)ifr.ifr_hwaddr.sa_data[2],
1268         	(unsigned char)ifr.ifr_hwaddr.sa_data[3],
1269         	(unsigned char)ifr.ifr_hwaddr.sa_data[4],
1270         	(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
1271	return mac;
1272}
1273
1274char *replace_str(char *st, char *orig, char *repl, char* buff) {
1275	char *ch;
1276	if (!(ch = strstr(st, orig)))
1277		return st;
1278	strncpy(buff, st, ch-st);
1279	buff[ch-st] = 0;
1280	sprintf(buff+(ch-st), "%s%s", repl, ch+strlen(orig));
1281
1282	return buff;
1283}
1284
1285//- �P�_�}�l�������m
1286int startposizition( char *str, int start )
1287{
1288	int i=0;            //-�����p��
1289    int posizition=0;   //- ���^���m
1290    int tempposi=start;
1291    while(str[tempposi]<0)
1292    {
1293    	i++;
1294        tempposi--;
1295    }
1296
1297    if(i%2==0 && i!=0)
1298    	posizition=start+1;
1299    else
1300    	posizition=start;
1301    return posizition;
1302}
1303
1304//- �P�_�����������m
1305int endposizition( char *str, int end )
1306{
1307	int i=0;            //-�����p��
1308	int posizition=0;   //- ���^���m
1309	int tempposi=end;
1310	while(str[tempposi]<0)
1311	{
1312		i++;
1313	    tempposi--;
1314	}
1315
1316	if(i%2==0 && i!=0)
1317		posizition=end;
1318	else
1319	    posizition=end-1;
1320
1321 	return posizition;
1322}
1323
1324void getStr( char *str, char *substr, int substrlen, int start, int end )
1325{
1326	int  i=0;
1327	char* temp;
1328	temp = (char*)malloc(substrlen);
1329	memset(temp,0,sizeof(temp));
1330
1331	for( start; start<=end; start++ )
1332    {
1333       	temp[i]=str[start];
1334        i++;
1335    }
1336    temp[i]='\0';
1337	strcpy(substr,temp);
1338
1339	free(temp);
1340}
1341
1342void  getSubStr( char *str, char *substr, int start, int end )
1343{
1344	int substrlen = end - start + 1;
1345    start = startposizition( str, start );
1346    end   = endposizition( str, end );
1347	getStr( str, substr, substrlen, start, end );
1348}
1349
1350const char *get_filename_ext(const char *filename) {
1351    const char *dot = strrchr(filename, '.');
1352    if(!dot || dot == filename) return "";
1353    return dot + 1;
1354}
1355
1356int extract_filename(const char* src, char** out){
1357	const char *splash = strrchr(src, '/');
1358    if(!splash || splash == src) return 0;
1359	int len = strlen(src) - (splash - src) + 1;
1360	*out = (char*)malloc(len+1);
1361	memset(*out, '\0', len+1);
1362	strcpy(*out, splash+1);
1363    return 1;
1364}
1365
1366int extract_filepath(const char* src, char** out){
1367	const char *splash = strrchr(src, '/');
1368    if(!splash || splash == src) return 0;
1369	int len = splash - src + 1;
1370	*out = (char*)malloc(len+1);
1371	memset(*out, '\0', len+1);
1372	strncpy(*out, src, len);
1373	return 1;
1374}
1375
1376int createDirectory(const char * path) {
1377
1378	char* p;
1379	struct stat st;
1380  	for( p = strchr(path+1, '/'); p; p = strchr(p+1, '/') ) {
1381    	*p='\0';
1382
1383		if( stat(path, &st) == -1 ){
1384		    if( mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO)==-1) {
1385				return 0;
1386		    }
1387		}
1388    	*p='/';
1389  	}
1390
1391	return 1;
1392
1393	/*
1394  	char * buffer = malloc((strlen(path) + 10) * sizeof(char));
1395  	sprintf(buffer, "mkdir -p %s", path);
1396  	int result = system(buffer);
1397  	free(buffer);
1398  	return result;
1399  	*/
1400}
1401
1402int smbc_wrapper_opendir(connection* con, const char *durl)
1403{
1404	int ret = -1;
1405
1406	if(con->mode== SMB_BASIC){
1407		ret = (int)smbc_opendir(durl);
1408	}
1409	else if(con->mode == SMB_NTLM){
1410		ret = (int)smbc_cli_opendir(con->smb_info->cli, durl);
1411	}
1412
1413	return ret;
1414}
1415
1416int smbc_wrapper_opensharedir(connection* con, const char *durl)
1417{
1418	int ret = -1;
1419
1420	if(con->mode== SMB_BASIC){
1421		ret = (int)smbc_opendir(durl);
1422	}
1423	else if(con->mode == SMB_NTLM){
1424		char turi[512];
1425		sprintf(turi, "%s\\IPC$", durl);
1426		ret = (int)smbc_cli_open_share(con->smb_info->cli, turi);
1427	}
1428
1429	return ret;
1430}
1431
1432struct smbc_dirent* smbc_wrapper_readdir(connection* con, unsigned int dh)
1433{
1434	if(con->mode== SMB_BASIC)
1435		return smbc_readdir(dh);
1436	else if(con->mode == SMB_NTLM)
1437		return smbc_cli_readdir(dh);
1438
1439	return NULL;
1440}
1441
1442int smbc_wrapper_closedir(connection* con, int dh)
1443{
1444	if(con->mode== SMB_BASIC)
1445		return smbc_closedir(dh);
1446	else if(con->mode == SMB_NTLM)
1447		return smbc_cli_closedir(dh);
1448
1449	return -1;
1450}
1451
1452int smbc_wrapper_stat(connection* con, const char *url, struct stat *st)
1453{
1454	if(con->mode== SMB_BASIC){
1455		return smbc_stat(url, st);
1456	}
1457	else if(con->mode == SMB_NTLM){
1458		return smbc_cli_stat(con->smb_info->cli, url, st);
1459	}
1460
1461	return -1;
1462
1463}
1464
1465int smbc_wrapper_unlink(connection* con, const char *furl)
1466{
1467	if(con->mode== SMB_BASIC)
1468		return smbc_unlink(furl);
1469	else if(con->mode == SMB_NTLM)
1470		return smbc_cli_unlink(con->smb_info->cli, furl, 0);
1471
1472	return -1;
1473}
1474
1475uint32_t smbc_wrapper_rmdir(connection* con, const char *dname)
1476{
1477	if(con->mode== SMB_BASIC)
1478		return smbc_rmdir(dname);
1479	else if(con->mode == SMB_NTLM)
1480		return smbc_cli_rmdir(con->smb_info->cli, dname);
1481
1482	return 0;
1483}
1484
1485uint32_t smbc_wrapper_mkdir(connection* con, const char *fname, mode_t mode)
1486{
1487	if(con->mode== SMB_BASIC)
1488		return smbc_mkdir(fname, mode);
1489	else if(con->mode == SMB_NTLM){
1490		smb_file_t *fp;
1491
1492		if((fp = smbc_cli_ntcreate(con->smb_info->cli, fname,
1493						FILE_READ_DATA | FILE_WRITE_DATA, FILE_CREATE, FILE_DIRECTORY_FILE)) == NULL)
1494		{
1495			return -1;
1496		}
1497		else{
1498			smbc_cli_close(con->smb_info->cli, fp);
1499		}
1500	}
1501
1502	return 0;
1503}
1504
1505uint32_t smbc_wrapper_rename(connection* con, char *src, char *dst)
1506{
1507	if(con->mode== SMB_BASIC)
1508		return smbc_rename(src, dst);
1509	else if(con->mode == SMB_NTLM)
1510		return smbc_cli_rename(con->smb_info->cli, src, dst);
1511
1512	return 0;
1513}
1514
1515int smbc_wrapper_open(connection* con, const char *furl, int flags, mode_t mode)
1516{
1517	if(con->mode== SMB_BASIC)
1518		return smbc_open(furl, flags, mode);
1519	else if(con->mode == SMB_NTLM)
1520		return smbc_cli_open(con->smb_info->cli, furl, flags);
1521
1522	return -1;
1523}
1524
1525int smbc_wrapper_create(connection* con, const char *furl, int flags, mode_t mode)
1526{
1527	if(con->mode== SMB_BASIC)
1528		return smbc_creat(furl, mode);
1529	else if(con->mode == SMB_NTLM)
1530		return smbc_cli_ntcreate(con->smb_info->cli, furl, flags, FILE_CREATE, mode);
1531
1532	return -1;
1533}
1534
1535int smbc_wrapper_close(connection* con, int fd)
1536{
1537	if(con->mode== SMB_BASIC)
1538		return smbc_close(fd);
1539	else if(con->mode == SMB_NTLM)
1540		return smbc_cli_close(con->smb_info->cli, fd);
1541
1542	return -1;
1543}
1544
1545size_t smbc_wrapper_read(connection* con, int fd, void *buf, size_t bufsize)
1546{
1547	if(con->mode== SMB_BASIC)
1548		return smbc_read(fd, buf, bufsize);
1549	else if(con->mode == SMB_NTLM)
1550		return smbc_cli_read(con->smb_info->cli, fd, buf, bufsize);
1551
1552	return -1;
1553}
1554
1555size_t smbc_wrapper_write(connection* con, int fd, const void *buf, size_t bufsize, uint16_t write_mode )
1556{
1557	if(con->mode== SMB_BASIC)
1558		return smbc_write(fd, buf, bufsize);
1559	else if(con->mode == SMB_NTLM)
1560		return smbc_cli_write(con->smb_info->cli, fd, write_mode, buf, bufsize);
1561
1562	return -1;
1563}
1564
1565off_t
1566smbc_wrapper_lseek(connection* con, int fd, off_t offset, int whence)
1567{
1568   if(con->mode== SMB_BASIC)
1569		return smbc_lseek(fd, offset,whence);
1570	else if(con->mode == SMB_NTLM)
1571		return smbc_cli_lseek(con->smb_info->cli, fd, offset,whence);
1572
1573	return -1;
1574}
1575int smbc_wrapper_parse_path(connection* con, char *pWorkgroup, char *pServer, char *pShare, char *pPath){
1576	if(con->mode== SMB_BASIC||con->mode== SMB_NTLM){
1577		smbc_parse_path(con->physical.path->ptr, pWorkgroup, pServer, pShare, pPath);
1578
1579		//- Jerry add: replace '\\' to '/'
1580		do{
1581			char buff[4096];
1582			strcpy( pPath, replace_str(&pPath[0],"\\","/", (char *)&buff[0]) );
1583		}while(strstr(pPath,"\\")!=NULL);
1584	}
1585
1586	return 1;
1587}
1588
1589int smbc_wrapper_parse_path2(connection* con, char *pWorkgroup, char *pServer, char *pShare, char *pPath){
1590	if(con->mode== SMB_BASIC||con->mode== SMB_NTLM){
1591
1592		smbc_parse_path(con->physical_auth_url->ptr, pWorkgroup, pServer, pShare, pPath);
1593
1594		int len = strlen(pPath)+1;
1595
1596		char* buff = (char*)malloc(len);
1597		memset(buff, '\0', len);
1598
1599		do{
1600			strcpy( pPath, replace_str(&pPath[0],"\\","/", buff) );
1601		}while(strstr(pPath,"\\")!=NULL);
1602
1603		free(buff);
1604	}
1605
1606	return 1;
1607}
1608
1609int smbc_parse_mnt_path(
1610	const char* physical_path,
1611	const char* mnt_path,
1612    int mnt_path_len,
1613    char** usbdisk_path,
1614    char** usbdisk_share_folder){
1615
1616	char* aa = physical_path + mnt_path_len;
1617	//Cdbg(1, "physical_path = %s, aa=%s", physical_path ,aa);
1618	char* bb = strstr(aa, "/");
1619	char* cc = NULL;
1620	//Cdbg(1, "bb=%s", bb);
1621	int len = 0;
1622	int len2 = 0;
1623	if(bb) {
1624		len=bb - aa;
1625		//Cdbg(1, "bb=%s", bb);
1626		cc = strstr(bb+1, "/");
1627		//Cdbg(1, "cc=%s", cc);
1628		if(cc) len2 = cc - bb;
1629		else len2 = strlen(bb);
1630	}
1631	else
1632		len = ( physical_path + strlen(physical_path) ) - aa;
1633	//Cdbg(1, "strlen(physical_path)=%d", strlen(physical_path));
1634	*usbdisk_path = (char*)malloc(len+mnt_path_len+1);
1635	memset( *usbdisk_path, '\0', len+mnt_path_len+1);
1636	strncpy( *usbdisk_path, physical_path, len+mnt_path_len);
1637	//Cdbg(1, "usbdisk_path=%s, len=%d, mnt_path_len=%d", *usbdisk_path, len, mnt_path_len);
1638	if(bb){
1639		*usbdisk_share_folder= (char*)malloc(len2+1);
1640		memset( *usbdisk_share_folder, '\0', len2+1);
1641		strncpy(*usbdisk_share_folder, bb+1, len2-1);
1642	}
1643	return 1;
1644}
1645
1646int isBrowser(connection *con){
1647	data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
1648	return ( ds && (strstr( ds->value->ptr, "Mozilla" ) || strstr( ds->value->ptr, "Opera" ))) ? 1 : 0;
1649}
1650
1651void smbc_wrapper_response_401(server *srv, connection *con)
1652{
1653	data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
1654
1655	//- Browser response
1656	if( ds && (strstr( ds->value->ptr, "Mozilla" )||strstr( ds->value->ptr, "Opera" )) ){
1657		if(con->mode == SMB_BASIC||con->mode == DIRECT){
1658			Cdbg(DBE, "con->mode == SMB_BASIC -> return 401");
1659			con->http_status = 401;
1660			return;
1661		}
1662	}
1663
1664	Cdbg(DBE, "smbc_wrapper_response_401 -> return 401");
1665
1666	char str[50];
1667
1668	UNUSED(srv);
1669
1670	buffer* tmp_buf = buffer_init();
1671	if(con->mode == SMB_BASIC){
1672		//sprintf(str, "Basic realm=\"%s\"", "smbdav");
1673
1674		if(con->smb_info&&con->smb_info->server->used)
1675			sprintf(str, "Basic realm=\"smb://%s\"", con->smb_info->server->ptr);
1676		else
1677			sprintf(str, "Basic realm=\"%s\"", "webdav");
1678	}
1679	else if(con->mode == SMB_NTLM)
1680		sprintf(str, "NTLM");
1681	else
1682		sprintf(str, "Basic realm=\"%s\"", "webdav");
1683
1684	buffer_copy_string(tmp_buf, str);
1685
1686	response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf));
1687	con->http_status = 401;
1688
1689	buffer_free(tmp_buf);
1690}
1691
1692void smbc_wrapper_response_realm_401(server *srv, connection *con)
1693{
1694/*
1695	if(con->mode == SMB_BASIC){
1696		if(con->smb_info&&con->smb_info->server->used){
1697			Cdbg(DBE, "sssssssss");
1698			con->http_status = 401;
1699		}
1700		return;
1701	}
1702	*/
1703	char str[50];
1704
1705	UNUSED(srv);
1706
1707	buffer* tmp_buf = buffer_init();
1708	if(con->mode == SMB_BASIC){
1709		//sprintf(str, "Basic realm=\"%s\"", "smbdav");
1710
1711		if(con->smb_info&&con->smb_info->server->used)
1712			sprintf(str, "Basic realm=\"smb://%s\"", con->smb_info->server->ptr);
1713		else
1714			sprintf(str, "Basic realm=\"%s\"", "webdav");
1715
1716	}
1717	else if(con->mode == SMB_NTLM)
1718		sprintf(str, "NTLM");
1719	else
1720		sprintf(str, "Basic realm=\"%s\"", "webdav");
1721
1722	buffer_copy_string(tmp_buf, str);
1723
1724	response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf));
1725	con->http_status = 401;
1726
1727	buffer_free(tmp_buf);
1728}
1729
1730void smbc_wrapper_response_404(server *srv, connection *con)
1731{
1732	char str[50];
1733
1734	UNUSED(srv);
1735	/*
1736	buffer* tmp_buf = buffer_init();
1737
1738	if(con->mode == SMB_BASIC)
1739		sprintf(str, "Basic realm=\"%s\"", "smbdav");
1740	else if(con->mode == SMB_NTLM)
1741		sprintf(str, "NTLM");
1742
1743	buffer_copy_string(tmp_buf, str);
1744	response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf));
1745	*/
1746	con->http_status = 404;
1747	//buffer_free(tmp_buf);
1748}
1749
1750buffer* smbc_wrapper_physical_url_path(server *srv, connection *con)
1751{
1752	if(con->mode==SMB_BASIC||con->mode==SMB_NTLM){
1753		return con->url.path;
1754	}
1755	return con->physical.path;
1756}
1757
1758int is_acc_account_existed(const char *username){
1759
1760	char *nvram_acc_list;
1761	int account_existed = 0;
1762	int len = 0;
1763
1764#if EMBEDDED_EANBLE
1765	char *acc_list = nvram_get_acc_list();
1766	if(acc_list==NULL)
1767		return 0;
1768
1769	len = strlen(acc_list);
1770	nvram_acc_list = (char *)malloc(sizeof(char)*(len+1));
1771	if(nvram_acc_list==NULL)
1772		return 0;
1773
1774	memset(nvram_acc_list, 0, len+1);
1775	strncpy(nvram_acc_list, acc_list, len);
1776
1777	#ifdef APP_IPKG
1778	free(acc_list);
1779	#endif
1780#else
1781	nvram_acc_list = (char*)malloc(100);
1782	if(nvram_acc_list==NULL)
1783		return 0;
1784
1785	strcpy(nvram_acc_list, "admin>admin<jerry>jerry");
1786#endif
1787
1788	if(nvram_acc_list!=NULL){
1789
1790		buffer* buffer_name = buffer_init();
1791		char * pch = strtok(nvram_acc_list, "<>");
1792
1793		while(pch!=NULL){
1794			//- User Name
1795			len = strlen(pch);
1796			buffer_copy_string_len(buffer_name, pch, len);
1797			buffer_urldecode_path(buffer_name);
1798
1799			if(buffer_is_equal_string(buffer_name, username, strlen(username))){
1800				account_existed = 1;
1801				break;
1802			}
1803
1804			//- User Password
1805			pch = strtok(NULL,"<>");
1806
1807			//- next
1808			pch = strtok(NULL,"<>");
1809		}
1810
1811		free(nvram_acc_list);
1812		buffer_free(buffer_name);
1813	}
1814
1815	return account_existed;
1816}
1817
1818int is_aicloud_account_existed(const char *username){
1819	aicloud_acc_info_t* c;
1820	for (c = aicloud_acc_info_list; c; c = c->next) {
1821
1822		if(buffer_is_equal_string(c->username, username, strlen(username))){
1823			return 1;
1824		}
1825	}
1826
1827	return 0;
1828}
1829
1830int is_account_existed(const char *username){
1831	if(is_acc_account_existed(username)==1){
1832		return 1;
1833	}
1834
1835	if(is_aicloud_account_existed(username)==1){
1836		return 1;
1837	}
1838
1839	return 0;
1840}
1841
1842account_type smbc_get_account_type(const char* user_name){
1843
1844	account_type var_type;
1845
1846	if(is_acc_account_existed(user_name)==1 || strncmp(user_name, "guest", 5)==0){
1847		var_type = T_ACCOUNT_SAMBA;
1848	}
1849	else if(is_aicloud_account_existed(user_name)==1){
1850		var_type = T_ACCOUNT_AICLOUD;
1851	}
1852	else
1853		return -1;
1854
1855	return var_type;
1856
1857}
1858
1859account_permission_type smbc_get_account_permission(const char* user_name){
1860
1861#if EMBEDDED_EANBLE
1862	if(strcmp( user_name, nvram_get_http_username())==0){
1863		return T_ADMIN;
1864	}
1865#else
1866	if(strcmp( user_name, "admin")==0){
1867		return T_ADMIN;
1868	}
1869#endif
1870
1871	return T_USER;
1872}
1873
1874int smbc_get_usbdisk_permission(const char* user_name, const char* usbdisk_rel_sub_path, const char* usbdisk_sub_share_folder)
1875{
1876	int permission = -1;
1877	account_type var_type = smbc_get_account_type(user_name);
1878
1879	if(var_type == T_ACCOUNT_SAMBA){
1880#if EMBEDDED_EANBLE
1881		int st_samba_mode = nvram_get_st_samba_mode();
1882
1883		if( (st_samba_mode==1) ||
1884		    (user_name!=NULL && strncmp(user_name, "guest", 5)==0))
1885			permission = 3;
1886		else{
1887			permission = get_permission( user_name,
1888									     usbdisk_rel_sub_path,
1889									     usbdisk_sub_share_folder,
1890									     "cifs");
1891		}
1892
1893		Cdbg(DBE, "usbdisk_rel_sub_path=%s, usbdisk_sub_share_folder=%s, permission=%d, user_name=%s",
1894					usbdisk_rel_sub_path, usbdisk_sub_share_folder, permission, user_name);
1895
1896#endif
1897	}
1898	else if(var_type == T_ACCOUNT_AICLOUD){
1899
1900#if EMBEDDED_EANBLE
1901
1902		permission = get_aicloud_permission( user_name,
1903											 usbdisk_rel_sub_path,
1904											 usbdisk_sub_share_folder);
1905#endif
1906	}
1907
1908	return permission;
1909}
1910
1911int hex2ten(const char* in_str )
1912{
1913	int ret;
1914
1915	if( in_str == (char*)'0' )
1916		ret = 0;
1917	else if( in_str == (char*)'1' )
1918		ret = 1;
1919	else if( in_str == (char*)'2' )
1920		ret = 2;
1921	else if( in_str == (char*)'3' )
1922		ret = 3;
1923	else if( in_str == (char*)'4' )
1924		ret = 4;
1925	else if( in_str == (char*)'5' )
1926		ret = 5;
1927	else if( in_str == (char*)'6' )
1928		ret = 6;
1929	else if( in_str == (char*)'7' )
1930		ret = 7;
1931	else if( in_str == (char*)'8' )
1932		ret = 8;
1933	else if( in_str == (char*)'9' )
1934		ret = 9;
1935	else if( in_str == (char*)'A' || in_str==(char*)'a' )
1936		ret = 10;
1937	else if( in_str==(char*)'B' || in_str==(char*)'b' )
1938		ret = 11;
1939	else if( in_str==(char*)'C' || in_str==(char*)'c' )
1940		ret = 12;
1941	else if( in_str==(char*)'D' || in_str==(char*)'d' )
1942		ret = 13;
1943	else if( in_str==(char*)'E' || in_str==(char*)'e' )
1944		ret = 14;
1945	else if( in_str==(char*)'F' || in_str==(char*)'f' )
1946		ret = 15;
1947	else
1948		ret = 0;
1949
1950	//Cdbg(1, "12121212, in_str=%c, ret=%d", in_str, ret);
1951	return ret;
1952}
1953
1954void ten2bin(int ten, char** out)
1955{
1956	char _array[5]="\0";
1957	_array[0] = '0';
1958	_array[1] = '0';
1959	_array[2] = '0';
1960	_array[3] = '0';
1961	int _count = 3;
1962
1963	while( ten > 0 ){
1964		//Cdbg(1, "_count=%d", _count);
1965
1966		if( ( ten%2 ) == 0 )
1967			_array[_count] = '0';
1968		else
1969			_array[_count] = '1';
1970		_count--;
1971		ten = ten/2;
1972	}
1973
1974	*out = (char*)malloc(5);
1975	memset(*out, '\0', 5);
1976	strcpy(*out, _array);
1977}
1978
1979void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
1980{
1981   	strncpy(dest, src + start, cnt);
1982   	dest[cnt] = 0;
1983}
1984
1985void hexstr2binstr(const char* in_str, char** out_str)
1986{
1987	char *tmp;
1988	buffer* ret = buffer_init();
1989	for (tmp = in_str; *tmp; ++tmp){
1990
1991		int ten = hex2ten( (char*)(*tmp) );
1992
1993		char* binStr;
1994		ten2bin(ten, &binStr);
1995		//Cdbg(1, "444, binStr=%s", binStr);
1996
1997		buffer_append_string_len(ret, binStr, 4);
1998
1999		free(binStr);
2000	}
2001
2002	*out_str = (char*)malloc(ret->size+1);
2003	strcpy(*out_str, ret->ptr);
2004	buffer_free(ret);
2005
2006}
2007
2008void ten2hex(int  _v, char** out )
2009{
2010	*out = (char*)malloc(5);
2011	memset(*out, '\0', 5);
2012	sprintf(*out, "%x", _v);
2013}
2014
2015void binstr2hexstr( const char* in_str, char** out_str )
2016{
2017	buffer* ret = buffer_init();
2018	if( 0 != strlen(in_str) % 4 )	{
2019		buffer_free(ret);
2020		return;
2021	}
2022
2023	buffer_copy_string(ret, "");
2024
2025	int ic = strlen(in_str) / 4;
2026	//Cdbg(DBE, "ic=%d", ic);
2027	for( int i = 0; i < ic; i++ )
2028	{
2029		char str[4]="\0";
2030		substr(str, in_str, i*4, 4);
2031
2032		int uc = bin2ten( str );
2033
2034		//- ten to hex
2035		char* hex;
2036		ten2hex(uc, &hex);
2037		buffer_append_string(ret, hex);
2038		free(hex);
2039	}
2040
2041	*out_str = (char*)malloc(ret->size+1);
2042	strcpy(*out_str, ret->ptr);
2043
2044	buffer_free(ret);
2045}
2046
2047void deinterleave( char* src, int charcnt, char** out )
2048{
2049	int src_len = strlen(src);
2050	int ic = src_len / charcnt;
2051	buffer* ret = buffer_init();
2052
2053	for( int i = 0; i < charcnt; i++ )
2054	{
2055		for( int j = 0; j < ic; j++ )
2056		{
2057			int x = (j*charcnt) + i;
2058
2059			char tmps[8]="\0";
2060			sprintf(tmps, "%c", *(src+x));
2061
2062			//Cdbg(1, "tmps =  %s", tmps);
2063			buffer_append_string(ret, tmps);
2064		}
2065
2066	}
2067
2068	*out = (char*)malloc(ret->size+1);
2069	strcpy(*out, ret->ptr);
2070
2071	buffer_free(ret);
2072}
2073
2074void interleave( char* src, int charcnt, char** out )
2075{
2076	int src_len = strlen(src);
2077	int ic = src_len / charcnt;
2078	buffer* ret = buffer_init();
2079
2080	for( int i = 0; i < ic; i++ )	{
2081		for( int j = 0; j < charcnt; j++ ) {
2082			//ret += src.charAt( (j * ic) + i );
2083
2084			int x = (j * ic) + i;
2085
2086			char tmps[8]="\0";
2087			sprintf(tmps, "%c", *(src+x));
2088
2089			//Cdbg(DBE, "tmps =  %s", tmps);
2090			buffer_append_string(ret, tmps);
2091		}
2092	}
2093
2094	*out = (char*)malloc(ret->size+1);
2095	strcpy(*out, ret->ptr);
2096
2097	buffer_free(ret);
2098	//Cdbg(DBE, "end interleave");
2099	/*
2100	// example: input string "ABCDEFG", charcnt = 3 --> "ADGBE0CF0"
2101	var ret = "";
2102	var ic = Math.ceil( src.length / charcnt );
2103	for( var i = 0; i < ic; i++ )	{
2104		for( var j = 0; j < charcnt; j++ )		{
2105			ret += src.charAt( (j * ic) + i );
2106		}
2107	}
2108	return ret;
2109	*/
2110}
2111
2112void str2hexstr(char* str, char* hex)
2113{
2114	const char* cHex = "0123456789ABCDEF";
2115	int i=0;
2116	for(int j =0; j < strlen(str); j++)
2117	{
2118		unsigned int a = (unsigned int) str[j];
2119		hex[i++] = cHex[(a & 0xf0) >> 4];
2120		hex[i++] = cHex[(a & 0x0f)];
2121	}
2122	hex = '\0';
2123}
2124
2125
2126
2127int sumhexstr( const char* str )
2128{
2129	int ret = 0;
2130	int ic = strlen(str) / 4.0;
2131	for( int i = 0; i < ic; i++ )
2132	{
2133		char t[4]="\0";
2134		substr(t, str, i*4, 4);
2135
2136		int j=0;
2137		int y = 0;
2138		char *tmp;
2139		for (tmp = t; *tmp; ++tmp){
2140			int pow = 1;
2141			for( int k = 0; k < strlen(t) - j - 1; k++ )
2142				pow *=16;
2143
2144			int x = hex2ten( *tmp ) * pow;
2145			y += x;
2146			j++;
2147		}
2148
2149		ret += y;
2150	}
2151
2152	return ret;
2153}
2154
2155int getshiftamount( const char* seed_str, const char* orignaldostr )
2156{
2157	char seed_hex_str[100]="\0";
2158	str2hexstr( seed_str, &seed_hex_str );
2159
2160	//sum hexstring, every 4digit (e.g "495a5c" => 0x495a + 0x5c => 0x49b6 => 18870;
2161	int sumhex = sumhexstr( seed_hex_str );
2162
2163	//limit shift value to lenght of seed
2164	int shiftamount = sumhex % strlen(orignaldostr);
2165	//Cdbg(1, "sumhex=%d, getshiftamount=%d", sumhex, strlen(orignaldostr));
2166	//ensure there is a shiftamount;
2167	if( shiftamount == 0 )
2168		shiftamount = 15;
2169	return shiftamount;
2170}
2171
2172void strleftshift( const char* str, int shiftamount, char** out )
2173{
2174	// e.g strleftshift("abcdef", 2) => "cdefab"
2175	char* aa = (char*)malloc(strlen(str)-shiftamount+1);
2176	memset(aa, "\0", strlen(str)-shiftamount+1);
2177	substr(aa, str, shiftamount, strlen(str)-shiftamount);
2178
2179	char *bb = (char*)malloc(shiftamount+1);
2180	memset(bb, "\0", shiftamount+1);
2181	substr(bb, str, 0, shiftamount);
2182
2183	*out = (char*)malloc(strlen(str)+1);
2184	memset(*out, "\0", strlen(str)+1);
2185	strcpy(*out , aa);
2186	strcat(*out, bb);
2187
2188	free(aa);
2189	free(bb);
2190}
2191
2192void strrightshift( const char* str, int shiftamount, char** out )
2193{
2194	// e.g strrightshift("abcdef", 2) => "efabcd"
2195	int len = strlen(str);
2196	//Cdbg(DBE, "11 len=%d, shiftamount=%d", len, shiftamount);
2197
2198	char* aa = (char*)malloc(shiftamount+1);
2199	memset(aa, "\0", shiftamount+1);
2200
2201	char *bb = (char*)malloc(len-shiftamount+1);
2202	memset(bb, "\0", len-shiftamount+1);
2203
2204	substr(aa, str, len-shiftamount, shiftamount);
2205	//Cdbg(DBE, "33 aa=%d -> %d", len-shiftamount, shiftamount);
2206
2207	substr(bb, str, 0, len-shiftamount);
2208	//Cdbg(DBE, "44 bb=%d -> %d", 0, len-shiftamount);
2209
2210	*out = (char*)malloc(len+1);
2211	memset(*out, "\0", strlen(str)+1);
2212
2213	strcpy(*out , aa);
2214	//Cdbg(DBE, "55 out=%s", *out);
2215	strcat(*out, bb);
2216	//Cdbg(DBE, "66 out=%s", *out);
2217
2218	free(aa);
2219	free(bb);
2220}
2221
2222int bin2ten( const char* _v )
2223{
2224	int ret = 0;
2225	for( int j = 0; j < strlen(_v); j++ )	{
2226		int pow = 1;
2227		for( int k = 0; k < strlen(_v) - j - 1; k++ )
2228			pow *=2;
2229
2230		char tmp[8]="\0";
2231		strncpy(tmp, _v+j, 1);
2232
2233		ret += atoi(tmp)*pow;
2234	}
2235	return ret;
2236}
2237
2238void binstr2str( const char* inbinstr, char** out )
2239{
2240	//�e���i���n��0
2241	if( 0 != strlen(inbinstr) % 8 )
2242	{
2243		return;
2244	}
2245
2246	int ic = strlen(inbinstr) / 8;
2247	int k = 0;
2248
2249	*out = (char*)malloc(ic+1);
2250	memset(*out , '\0', ic);
2251
2252	for( int i = 0; i < strlen(inbinstr); i+=8 )
2253	{
2254		//�e�|����
2255		char* substrupper = (char*)malloc(4);
2256		substr(substrupper, inbinstr, i, 4);
2257		int uc = bin2ten( substrupper );
2258		free(substrupper);
2259		substrupper=NULL;
2260
2261		//���|����
2262		char* substrlowwer = (char*)malloc(4);
2263		substr(substrlowwer, inbinstr,  i + 4, 4);
2264		int lc = bin2ten( substrlowwer );
2265		free(substrlowwer);
2266		substrlowwer=NULL;
2267
2268		int v = (uc << 4) | lc;
2269
2270		char out_char[8];
2271		sprintf(out_char, "%c", v);
2272
2273		strcat(*out, out_char);
2274		k++;
2275	}
2276
2277}
2278
2279void dec2Bin(int dec, char** out) {
2280
2281	char _array[8] = "00000000";
2282	int _count = 7;
2283
2284	while( dec > 0 ){
2285		//Cdbg(1, "_count=%d", _count);
2286
2287		if( ( dec%2 ) == 0 )
2288			_array[_count] = '0';
2289		else
2290			_array[_count] = '1';
2291		_count--;
2292		dec = dec/2;
2293	}
2294
2295	*out = (char*)malloc(8);
2296	memset(*out, '\0', 8);
2297	strncpy(*out, _array, 8);
2298}
2299
2300void str2binstr(const char* instr, char** out)
2301{
2302	buffer* b = buffer_init();
2303	int last = strlen(instr);
2304	for (int i = 0; i < last; i++) {
2305
2306		char tmp[8]="\0";
2307		strncpy(tmp, instr + i, 1);
2308
2309		int acsii_code = ((int)*tmp) & 0x000000ff;
2310		if (acsii_code < 128){
2311			char* binStr;
2312			dec2Bin(acsii_code, &binStr);
2313
2314			//Cdbg(1, "%s -> %d %d, binStr=%s", tmp, *tmp, acsii_code, binStr);
2315
2316			buffer_append_string_len(b, binStr, 8);
2317			//Cdbg(1, "b=%s", b->ptr);
2318
2319			free(binStr);
2320		}
2321
2322
2323	}
2324
2325	//Cdbg(1, "11111111111111 %d %d %d", b->used, last*8, b->size+1);
2326
2327	int len = last*8 + 1;
2328	*out = (char*)malloc(len);
2329	memset(*out, '\0', len);
2330	strcpy(*out, b->ptr);
2331	buffer_free(b);
2332}
2333
2334char* x123_decode(const char* in_str, const char* key, char* out_str)
2335{
2336	//Cdbg(DBE, "in_str=%s, key=%s", in_str, key);
2337
2338	char* ibinstr;
2339	hexstr2binstr( in_str, &ibinstr );
2340	//Cdbg(1, "ibinstr=%s", ibinstr);
2341
2342	char* binstr;
2343	deinterleave( ibinstr, 8, &binstr );
2344	//Cdbg(1, "deinterleave, binstr=%s", binstr);
2345
2346	int shiftamount = getshiftamount( key, binstr );
2347	//Cdbg(1, "shiftamount %d %s", shiftamount, key);
2348
2349	char* unshiftbinstr;
2350	strleftshift( binstr, shiftamount, &unshiftbinstr );
2351	//Cdbg(1, "unshiftbinstr %s", unshiftbinstr);
2352
2353	binstr2str(unshiftbinstr, &out_str);
2354	//Cdbg(DBE, "out_str %s", out_str);
2355
2356	free(ibinstr);
2357	free(binstr);
2358	free(unshiftbinstr);
2359
2360	return out_str;
2361}
2362
2363char* x123_encode(const char* in_str, const char* key, char* out_str)
2364{
2365	//Cdbg(DBE, "in_str=%s, key=%s", in_str, key);
2366
2367	char* ibinstr;
2368	str2binstr( in_str, &ibinstr );
2369	//Cdbg(DBE, "ibinstr = %s", ibinstr);
2370
2371	int shiftamount = getshiftamount( key, ibinstr );
2372	//Cdbg(DBE, "shiftamount = %d", shiftamount);
2373
2374	char* unshiftbinstr = NULL;
2375	strrightshift( ibinstr, shiftamount, &unshiftbinstr );
2376	//Cdbg(DBE, "unshiftbinstr = %s", unshiftbinstr);
2377
2378	char* binstr;
2379	interleave( unshiftbinstr, 8, &binstr );
2380	//Cdbg(DBE, "binstr = %s", binstr);
2381
2382	char* hexstr;
2383	binstr2hexstr(binstr, &hexstr);
2384	//Cdbg(DBE, "hexstr = %s", hexstr);
2385
2386	int out_len = strlen(hexstr)+9;
2387	//Cdbg(DBE, "out_len = %d, %d", out_len, strlen(hexstr));
2388
2389	out_str = (char*)malloc(out_len);
2390	memset(out_str , '\0', out_len);
2391	strcpy(out_str, "ASUSHARE");
2392	strcat(out_str, hexstr);
2393
2394	free(unshiftbinstr);
2395	free(ibinstr);
2396	free(binstr);
2397	free(hexstr);
2398
2399	return out_str;
2400}
2401
2402void md5String(const char* input1, const char* input2, char** out)
2403{
2404	int i;
2405
2406	buffer* b = buffer_init();
2407	unsigned char signature[16];
2408	MD5_CTX ctx;
2409	MD5_Init(&ctx);
2410
2411	if(input1){
2412		//Cdbg(1, "input1 %s", input1);
2413		MD5_Update(&ctx, input1, strlen(input1));
2414	}
2415
2416	if(input2){
2417		//Cdbg(1, "input2 %s", input2);
2418		MD5_Update(&ctx, input2, strlen(input2));
2419	}
2420
2421	MD5_Final(signature, &ctx);
2422	char tempstring[2];
2423
2424	for(i=0; i<16; i++){
2425		int x = signature[i]/16;
2426		sprintf(tempstring, "%x", x);
2427		buffer_append_string(b, tempstring);
2428
2429		int y = signature[i]%16;
2430		sprintf(tempstring, "%x", y);
2431		buffer_append_string(b, tempstring);
2432	}
2433
2434	//Cdbg(1, "result %s", b->ptr);
2435
2436	int len = b->used + 1;
2437	*out = (char*)malloc(len);
2438	memset(*out, '\0', len);
2439	strcpy(*out, b->ptr);
2440	buffer_free(b);
2441
2442}
2443
2444int smbc_parser_basic_authentication(server *srv, connection* con, char** username,  char** password){
2445
2446	if (con->mode != SMB_BASIC&&con->mode != DIRECT) return 0;
2447
2448	data_string* ds = (data_string *)array_get_element(con->request.headers, "Authorization");
2449
2450	if(con->share_link_basic_auth->used){
2451		ds = data_string_init();
2452		buffer_copy_buffer( ds->value, con->share_link_basic_auth );
2453		buffer_reset(con->share_link_basic_auth);
2454	}
2455
2456	if (ds != NULL) {
2457		char *http_authorization = NULL;
2458		http_authorization = ds->value->ptr;
2459
2460		if(strncmp(http_authorization, "Basic ", 6) == 0) {
2461			buffer *basic_msg = buffer_init();
2462			buffer *user = buffer_init();
2463			buffer *pass = buffer_init();
2464
2465			if (!base64_decode(basic_msg, &http_authorization[6])) {
2466				log_error_write(srv, __FILE__, __LINE__, "sb", "decodeing base64-string failed", basic_msg);
2467				buffer_free(basic_msg);
2468				free(user);
2469				free(pass);
2470				return 0;
2471			}
2472			char *s, bmsg[1024] = {0};
2473
2474			//fetech the username and password from credential
2475			memcpy(bmsg, basic_msg->ptr, basic_msg->used);
2476			s = strchr(bmsg, ':');
2477			bmsg[s-bmsg] = '\0';
2478
2479			buffer_copy_string(user, bmsg);
2480			buffer_copy_string(pass, s+1);
2481
2482			*username = (char*)malloc(user->used);
2483			strcpy(*username, user->ptr);
2484
2485			*password = (char*)malloc(pass->used);
2486			strcpy(*password, pass->ptr);
2487
2488			buffer_free(basic_msg);
2489			free(user);
2490			free(pass);
2491
2492			Cdbg(DBE, "base64_decode=[%s][%s]", *username, *password);
2493
2494			return 1;
2495		}
2496	}
2497	else
2498		Cdbg(DBE, "smbc_parser_basic_authentication: ds == NULL, %s", con->url.path->ptr);
2499
2500	return 0;
2501}
2502
2503const char* g_temp_sharelink_file = "/tmp/sharelink";
2504
2505int generate_sharelink(server* srv,
2506			               connection *con,
2507			               const char* filename,
2508			               const char* url,
2509			               const char* base64_auth,
2510			               int expire,
2511			               int toShare,
2512			               buffer** out){
2513
2514	if(filename==NULL||url==NULL||base64_auth==NULL)
2515		return 0;
2516
2517#if 1
2518	if(toShare==1){
2519		char * pch;
2520		pch = strtok(filename, ";");
2521
2522		*out = buffer_init();
2523
2524		while(pch!=NULL){
2525
2526			char share_link[1024];
2527			struct timeval tv;
2528			unsigned long long now_utime;
2529			gettimeofday(&tv,NULL);
2530			now_utime = tv.tv_sec * 1000000 + tv.tv_usec;
2531			sprintf( share_link, "AICLOUD%d", abs(now_utime));
2532
2533			share_link_info_t *share_link_info;
2534			share_link_info = (share_link_info_t *)calloc(1, sizeof(share_link_info_t));
2535
2536			share_link_info->shortpath = buffer_init();
2537			buffer_copy_string(share_link_info->shortpath, share_link);
2538
2539			share_link_info->realpath = buffer_init();
2540			buffer_copy_string(share_link_info->realpath, url);
2541			buffer_urldecode_path(share_link_info->realpath);
2542
2543			share_link_info->filename = buffer_init();
2544			buffer_copy_string(share_link_info->filename, pch);
2545			buffer_urldecode_path(share_link_info->filename);
2546
2547			share_link_info->auth = buffer_init();
2548			buffer_copy_string(share_link_info->auth, base64_auth);
2549
2550			share_link_info->createtime = time(NULL);
2551			share_link_info->expiretime = (expire==0 ? 0 : share_link_info->createtime + expire);
2552			share_link_info->toshare = toShare;
2553
2554			DLIST_ADD(share_link_info_list, share_link_info);
2555
2556			buffer_append_string(*out, share_link);
2557			buffer_append_string_len(*out, CONST_STR_LEN("/"));
2558			buffer_append_string(*out, pch);
2559
2560			//- Next
2561			pch = strtok(NULL,";");
2562
2563			if(pch)
2564				buffer_append_string_len(*out, CONST_STR_LEN(";"));
2565
2566			log_sys_write(srv, "sbsbss", "Create share link", share_link_info->realpath , "/", share_link_info->filename, "from ip", con->dst_addr_buf->ptr);
2567
2568		}
2569	}
2570	else{
2571		char * pch;
2572		pch = strtok(filename, ";");
2573
2574		*out = buffer_init();
2575
2576		char strTime[20]="\0";
2577		char mac[20]="\0";
2578
2579	#if EMBEDDED_EANBLE
2580		#ifdef APP_IPKG
2581        char *router_mac=nvram_get_router_mac();
2582        sprintf(mac,"%s",router_mac);
2583        free(router_mac);
2584		#else
2585		char *router_mac=nvram_get_router_mac();
2586		strcpy(mac, (router_mac==NULL) ? "00:12:34:56:78:90" : router_mac);
2587		#endif
2588	#else
2589		get_mac_address("eth0", &mac);
2590	#endif
2591
2592		char* base64_key = ldb_base64_encode(mac, strlen(mac));
2593
2594		expire = 86400; //- 24hr
2595		unsigned long expiretime = (expire==0 ? 0 : time(NULL) + expire);
2596		sprintf(strTime, "%lu", expiretime);
2597
2598		char* share_link;
2599		char* urlstr = (char*)malloc(strlen(url) +  strlen(base64_auth) + strlen(strTime) + 15);
2600		sprintf(urlstr, "%s?auth=%s&expire=%s", url, base64_auth, strTime);
2601		Cdbg(DBE, "urlstr=%s", urlstr);
2602		share_link = x123_encode(urlstr, base64_key, &share_link);
2603		Cdbg(DBE, "share_link=%s", share_link);
2604
2605		while(pch!=NULL){
2606			buffer_append_string(*out, share_link);
2607			buffer_append_string_len(*out, CONST_STR_LEN("/"));
2608			buffer_append_string(*out, pch);
2609
2610			//- Next
2611			pch = strtok(NULL,";");
2612
2613			if(pch)
2614				buffer_append_string_len(*out, CONST_STR_LEN(";"));
2615		}
2616
2617		//Cdbg(1, "out=%s", (*out)->ptr);
2618
2619		if(base64_key){
2620			free(base64_key);
2621			base64_key=NULL;
2622		}
2623
2624		if(urlstr){
2625			free(urlstr);
2626			urlstr=NULL;
2627		}
2628
2629		if(share_link){
2630			free(share_link);
2631			share_link=NULL;
2632		}
2633
2634		//share_link = x123_encode("sambapc/sharefolder", "abcdefg", &share_link);
2635		//char* decode_str;
2636		//decode_str = x123_decode(encode_str, ldb_base64_encode(mac, strlen(mac)), &decode_str);
2637		//Cdbg(DBE, "do HTTP_METHOD_GSL decode_str=%s", decode_str);
2638	}
2639#else
2640
2641#if 1
2642	char * pch;
2643	pch = strtok(filename, ";");
2644
2645	*out = buffer_init();
2646
2647	while(pch!=NULL){
2648
2649		char share_link[1024];
2650		struct timeval tv;
2651		unsigned long long now_utime;
2652		gettimeofday(&tv,NULL);
2653		now_utime = tv.tv_sec * 1000000 + tv.tv_usec;
2654		sprintf( share_link, "AICLOUD%d", abs(now_utime));
2655
2656		share_link_info_t *share_link_info;
2657		share_link_info = (share_link_info_t *)calloc(1, sizeof(share_link_info_t));
2658
2659		share_link_info->shortpath = buffer_init();
2660		buffer_copy_string(share_link_info->shortpath, share_link);
2661
2662		share_link_info->realpath = buffer_init();
2663		buffer_copy_string(share_link_info->realpath, url);
2664		buffer_urldecode_path(share_link_info->realpath);
2665
2666		share_link_info->filename = buffer_init();
2667		buffer_copy_string(share_link_info->filename, pch);
2668		buffer_urldecode_path(share_link_info->filename);
2669
2670		share_link_info->auth = buffer_init();
2671		buffer_copy_string(share_link_info->auth, base64_auth);
2672
2673		share_link_info->createtime = time(NULL);
2674		share_link_info->expiretime = (expire==0 ? 0 : share_link_info->createtime + expire);
2675		share_link_info->toshare = toShare;
2676
2677		DLIST_ADD(share_link_info_list, share_link_info);
2678
2679		buffer_append_string(*out, share_link);
2680		buffer_append_string_len(*out, CONST_STR_LEN("/"));
2681		buffer_append_string(*out, pch);
2682
2683		//- Next
2684		pch = strtok(NULL,";");
2685
2686		if(pch)
2687			buffer_append_string_len(*out, CONST_STR_LEN(";"));
2688
2689		if(toShare==1)
2690			log_sys_write(srv, "sbsbss", "Create share link", share_link_info->realpath , "/", share_link_info->filename, "from ip", con->dst_addr_buf->ptr);
2691
2692	}
2693#else
2694	char mac[20]="\0";
2695	get_mac_address("eth0", &mac);
2696
2697	char* base64_auth = ldb_base64_encode(auth, strlen(auth));
2698	char* base64_key = ldb_base64_encode(mac, strlen(mac));
2699	char* urlstr = (char*)malloc(buffer_url->size +  strlen(base64_auth) + strlen(strTime) + 15);
2700	sprintf(urlstr, "%s?auth=%s&expire=%s", buffer_url->ptr, base64_auth, strTime);
2701
2702	share_link = x123_encode(urlstr, base64_key, &share_link);
2703	//share_link = x123_encode("sambapc/sharefolder", "abcdefg", &share_link);
2704	free(base64_auth);
2705	free(base64_key);
2706	free(urlstr);
2707
2708	Cdbg(DBE, "do HTTP_METHOD_GSL urlstr=%s, share_link=%s", urlstr, share_link);
2709
2710	//char* decode_str;
2711	//decode_str = x123_decode(encode_str, ldb_base64_encode(mac, strlen(mac)), &decode_str);
2712	//Cdbg(DBE, "do HTTP_METHOD_GSL decode_str=%s", decode_str);
2713#endif
2714#endif
2715
2716	return 1;
2717
2718}
2719
2720int get_sharelink_save_count(){
2721	int count = 0;
2722	share_link_info_t* c;
2723	time_t cur_time = time(NULL);
2724	for (c = share_link_info_list; c; c = c->next) {
2725		if(c->toshare != 0){
2726			double offset = difftime(c->expiretime, cur_time);
2727			if( c->expiretime == 0 || offset >= 0.0 ){
2728				count++;
2729			}
2730		}
2731	}
2732	Cdbg(DBE, "get_sharelink_save_count=%d", count);
2733	return count;
2734}
2735
2736void save_sharelink_list(){
2737	share_link_info_t* c;
2738	time_t cur_time = time(NULL);
2739
2740	buffer* sharelink_list = buffer_init();
2741	buffer_copy_string(sharelink_list, "");
2742
2743	for (c = share_link_info_list; c; c = c->next) {
2744
2745		double offset = difftime(c->expiretime, cur_time);
2746		if( c->expiretime !=0 && offset < 0.0 ){
2747			share_link_info_t* c_prev = c->prev;
2748			free_share_link_info(c);
2749			DLIST_REMOVE(share_link_info_list, c);
2750			free(c);
2751			c = c_prev;
2752			continue;
2753		}
2754
2755		if(c->toshare != 0){
2756
2757			buffer* temp = buffer_init();
2758
2759			buffer_copy_buffer(temp, c->shortpath);
2760			buffer_append_string(temp, ">");
2761			buffer_append_string_buffer(temp, c->realpath);
2762			buffer_append_string(temp, ">");
2763			buffer_append_string_buffer(temp, c->filename);
2764			//buffer_append_string_encoded(temp, CONST_BUF_LEN(c->filename), ENCODING_REL_URI);
2765			buffer_append_string(temp, ">");
2766			buffer_append_string_buffer(temp, c->auth);
2767			buffer_append_string(temp, ">");
2768
2769			char strTime[25] = {0};
2770			sprintf(strTime, "%lu", c->expiretime);
2771			buffer_append_string(temp, strTime);
2772
2773			buffer_append_string(temp, ">");
2774			char strTime2[25] = {0};
2775			sprintf(strTime2, "%lu", c->createtime);
2776			buffer_append_string(temp, strTime2);
2777
2778			buffer_append_string(temp, ">");
2779			char toshare[5] = {0};
2780			sprintf(toshare, "%d", c->toshare);
2781			buffer_append_string(temp, toshare);
2782
2783			buffer_append_string(temp, "<");
2784
2785			buffer_append_string_buffer(sharelink_list, temp);
2786
2787			buffer_free(temp);
2788		}
2789
2790	}
2791
2792#if EMBEDDED_EANBLE
2793	nvram_set_sharelink_str(sharelink_list->ptr);
2794#else
2795	unlink(g_temp_sharelink_file);
2796	FILE* fp = fopen(g_temp_sharelink_file, "w");
2797	if(fp!=NULL){
2798		fprintf(fp, "%s", sharelink_list->ptr);
2799		fclose(fp);
2800	}
2801#endif
2802
2803	buffer_free(sharelink_list);
2804
2805	//Cdbg(1, "save sharelink array length = %d", get_sharelink_save_count());
2806}
2807
2808void free_share_link_info(share_link_info_t *smb_sharelink_info){
2809	buffer_free(smb_sharelink_info->shortpath);
2810	buffer_free(smb_sharelink_info->realpath);
2811	buffer_free(smb_sharelink_info->filename);
2812	buffer_free(smb_sharelink_info->auth);
2813}
2814
2815void read_sharelink_list(){
2816
2817	char *nvram_sharelink = NULL;
2818
2819#if EMBEDDED_EANBLE
2820	nvram_sharelink = nvram_get_sharelink_str();
2821#else
2822	nvram_sharelink = read_whole_file(g_temp_sharelink_file);
2823#endif
2824
2825	if(nvram_sharelink==NULL){
2826		return;
2827	}
2828
2829	char* str_sharelink_list = (char*)malloc(strlen(nvram_sharelink)+1);
2830	strcpy(str_sharelink_list, nvram_sharelink);
2831
2832#ifdef APP_IPKG
2833	free(nvram_sharelink);
2834#endif
2835
2836	if(str_sharelink_list==NULL)
2837		return;
2838
2839	char *pch, *pch2, *saveptr=NULL, *saveptr2=NULL;
2840	pch = strtok_r(str_sharelink_list, "<", &saveptr);
2841	Cdbg(DBE, "pch=%s", pch);
2842
2843	while(pch!=NULL){
2844		char* tmp = strdup(pch);
2845
2846		pch2 = strtok_r(tmp, ">", &saveptr2);
2847		Cdbg(DBE, "pch2=%s", pch2);
2848
2849		while(pch2!=NULL){
2850
2851			//pch2 = strtok_r(NULL, ">", &saveptr2);
2852
2853			int b_addto_list = 1;
2854
2855			share_link_info_t *smb_sharelink_info;
2856			smb_sharelink_info = (share_link_info_t *)calloc(1, sizeof(share_link_info_t));
2857
2858			//- Share Path
2859			if(pch2){
2860				Cdbg(DBE, "share path=%s", pch2);
2861				smb_sharelink_info->shortpath = buffer_init();
2862				buffer_copy_string_len(smb_sharelink_info->shortpath, pch2, strlen(pch2));
2863			}
2864
2865			//- Real Path
2866			pch2 = strtok_r(NULL, ">", &saveptr2);
2867			if(pch2){
2868				Cdbg(DBE, "real path=%s", pch2);
2869				smb_sharelink_info->realpath = buffer_init();
2870				buffer_copy_string_len(smb_sharelink_info->realpath, pch2, strlen(pch2));
2871			}
2872
2873			//- File Name
2874			pch2 = strtok_r(NULL, ">", &saveptr2);
2875			if(pch2){
2876				Cdbg(DBE, "file name=%s", pch2);
2877				smb_sharelink_info->filename = buffer_init();
2878				buffer_copy_string_len(smb_sharelink_info->filename, pch2, strlen(pch2));
2879			}
2880
2881			//- Auth
2882			pch2 = strtok_r(NULL, ">", &saveptr2);
2883			if(pch2){
2884				Cdbg(DBE, "auth=%s", pch2);
2885				smb_sharelink_info->auth = buffer_init();
2886				buffer_copy_string_len(smb_sharelink_info->auth, pch2, strlen(pch2));
2887			}
2888
2889			//- Expire Time
2890			pch2 = strtok_r(NULL, ">", &saveptr2);
2891			if(pch2){
2892				smb_sharelink_info->expiretime = atoi(pch2);
2893				time_t cur_time = time(NULL);
2894				double offset = difftime(smb_sharelink_info->expiretime, cur_time);
2895				if( smb_sharelink_info->expiretime !=0 && offset < 0.0 ){
2896					free_share_link_info(smb_sharelink_info);
2897					free(smb_sharelink_info);
2898					b_addto_list = 0;
2899				}
2900			}
2901
2902			//- Create Time
2903			pch2 = strtok_r(NULL, ">", &saveptr2);
2904			if(pch2){
2905				Cdbg(DBE, "createtime=%s", pch2);
2906				smb_sharelink_info->createtime = atoi(pch2);
2907			}
2908
2909			//- toShare
2910			pch2 = strtok_r(NULL, ">", &saveptr2);
2911			if(pch2){
2912				Cdbg(DBE, "toshare=%s", pch2);
2913				smb_sharelink_info->toshare = atoi(pch2);
2914			}
2915
2916			if(b_addto_list==1)
2917				DLIST_ADD(share_link_info_list, smb_sharelink_info);
2918
2919			//- Next
2920			pch2 = strtok_r(NULL, ">", &saveptr2);
2921		}
2922
2923		if(tmp!=NULL)
2924			free(tmp);
2925
2926		pch = strtok_r(NULL, "<", &saveptr);
2927	}
2928
2929}
2930
2931void start_arpping_process(const char* scan_interface)
2932{
2933#if EMBEDDED_EANBLE
2934	if(pids("lighttpd-arpping"))
2935		return;
2936#else
2937	if(system("pidof lighttpd-arpping") == 0)
2938		return;
2939#endif
2940
2941	char cmd[BUFSIZ]="\0";
2942	/*
2943	char mybuffer[BUFSIZ]="\0";
2944	FILE* fp = popen("pwd", "r");
2945	if(fp){
2946		int len = fread(mybuffer, sizeof(char), BUFSIZ, fp);
2947		mybuffer[len-1]="\0";
2948		pclose(fp);
2949
2950		sprintf(cmd, ".%s/_inst/sbin/lighttpd-arpping -f %s &", mybuffer, scan_interface);
2951		Cdbg(DBE, "%s, len=%d", cmd, len);
2952		system(cmd);
2953	}
2954	*/
2955#ifndef APP_IPKG
2956#if EMBEDDED_EANBLE
2957	sprintf(cmd, "/usr/sbin/lighttpd-arpping -f %s &", scan_interface);
2958#else
2959	sprintf(cmd, "./_inst/sbin/lighttpd-arpping -f %s &", scan_interface);
2960#endif
2961#else
2962#if EMBEDDED_EANBLE
2963    sprintf(cmd, "/opt/bin/lighttpd-arpping -f %s &", scan_interface);
2964#else
2965    sprintf(cmd, "./_inst/sbin/lighttpd-arpping -f %s &", scan_interface);
2966#endif
2967#endif
2968	system(cmd);
2969
2970}
2971
2972void stop_arpping_process()
2973{
2974	FILE *fp;
2975    char buf[256];
2976    pid_t pid = 0;
2977    int n;
2978
2979	if ((fp = fopen(LIGHTTPD_ARPPING_PID_FILE_PATH, "r")) != NULL) {
2980		if (fgets(buf, sizeof(buf), fp) != NULL)
2981	    	pid = strtoul(buf, NULL, 0);
2982	    fclose(fp);
2983	}
2984
2985	if (pid > 1 && kill(pid, SIGTERM) == 0) {
2986		n = 10;
2987	    while ((kill(pid, SIGTERM) == 0) && (n-- > 0)) {
2988	    	Cdbg(DBE,"Mod_smbdav: %s: waiting pid=%d n=%d\n", __FUNCTION__, pid, n);
2989	        usleep(100 * 1000);
2990	    }
2991	}
2992
2993	unlink(LIGHTTPD_ARPPING_PID_FILE_PATH);
2994}
2995
2996int in_the_same_folder(buffer *src, buffer *dst)
2997{
2998	char *sp;
2999
3000	char *smem = (char *)malloc(src->used);
3001	memcpy(smem, src->ptr, src->used);
3002
3003	char *dmem = (char *)malloc(dst->used);
3004	memcpy(dmem, dst->ptr, dst->used);
3005
3006	sp = strrchr(smem, '/');
3007	int slen = sp - smem;
3008	sp = strrchr(dmem, '/');
3009	int dlen = sp - dmem;
3010
3011	smem[slen] = '\0';
3012	dmem[dlen] = '\0';
3013
3014	int res = memcmp(smem, dmem, (slen>dlen) ? slen : dlen);
3015	Cdbg(DBE, "smem=%s,dmem=%s, slen=%d, dlen=%d", smem, dmem, slen, dlen);
3016	free(smem);
3017	free(dmem);
3018
3019	return (res) ? 0 : 1;
3020}
3021
3022int is_dms_ipk_enabled(void)
3023{
3024    FILE* fp2;
3025    char line[128];
3026    char ms_enable[20]="\0";
3027    int result = 0;
3028    if((fp2 = fopen("/opt/lib/ipkg/info/mediaserver.control", "r")) != NULL){
3029            memset(line, 0, sizeof(line));
3030            while(fgets(line, 128, fp2) != NULL){
3031                    if(strncmp(line, "Enabled:", 8)==0){
3032                            strncpy(ms_enable, line + 9, strlen(line)-8);
3033                    }
3034            }
3035            fclose(fp2);
3036    }
3037    Cdbg(DBE, "ms_enable=%s\n", ms_enable);
3038    if(strncmp(ms_enable,"yes",strlen("yes")) == 0)
3039        result = 1;
3040    //fprintf(stderr,"ms_enable=%s,result=%d\n", ms_enable,result);
3041    return result;
3042}
3043
3044
3045int is_dms_enabled(void){
3046	int result = 0;
3047
3048#if EMBEDDED_EANBLE
3049	char *dms_enable = nvram_get_dms_enable();
3050	char *ms_dlna = NULL;
3051
3052	if(NULL == dms_enable || strcmp(dms_enable, "") == 0)
3053	{
3054		ms_dlna = nvram_get_ms_enable();
3055	}
3056#else
3057	char *dms_enable = "1";
3058	char *ms_dlna = NULL;
3059#endif
3060
3061	if(NULL != dms_enable && strcmp( dms_enable, "1" ) == 0)
3062		result = 1;
3063        else if(NULL != ms_dlna && strcmp( ms_dlna, "1" ) == 0)
3064        {
3065            if(0 == access("/opt/lib/ipkg/info/mediaserver.control",F_OK))
3066            {
3067                result = is_dms_ipk_enabled();
3068            }
3069            else
3070            {
3071                result = 0;
3072            }
3073         }
3074
3075#if EMBEDDED_EANBLE
3076#ifdef APP_IPKG
3077	if(dms_enable)
3078		free(dms_enable);
3079	if(ms_dlna)
3080		free(ms_dlna);
3081#endif
3082#endif
3083
3084	return result;
3085}
3086
3087#if 0
3088int smbc_host_account_authentication(connection* con, const char *username, const char *password){
3089
3090	char *nvram_acc_list, *nvram_acc_webdavproxy;
3091	int st_samba_mode = 1;
3092	if (con->mode != SMB_BASIC&&con->mode != DIRECT) return -1;
3093#if EMBEDDED_EANBLE
3094	char *a = nvram_get_acc_list();
3095	if(a==NULL) return -1;
3096	int l = strlen(a);
3097	nvram_acc_list = (char*)malloc(l+1);
3098	strncpy(nvram_acc_list, a, l);
3099	nvram_acc_list[l] = '\0';
3100#ifdef APP_IPKG
3101	free(a);
3102#endif
3103	char *b = nvram_get_acc_webdavproxy();
3104	if(b==NULL) return -1;
3105	l = strlen(b);
3106	nvram_acc_webdavproxy = (char*)malloc(l+1);
3107	strncpy(nvram_acc_webdavproxy, b, l);
3108	nvram_acc_webdavproxy[l] = '\0';
3109#ifdef APP_IPKG
3110	free(b);
3111#endif
3112	st_samba_mode = nvram_get_st_samba_mode();
3113#else
3114	int i = 100;
3115	nvram_acc_list = (char*)malloc(100);
3116	strcpy(nvram_acc_list, "admin<admin>jerry<jerry");
3117
3118	nvram_acc_webdavproxy = (char*)malloc(100);
3119	strcpy(nvram_acc_webdavproxy, "admin<1>jerry<0");
3120#endif
3121
3122	int found_account = 0, account_right = -1;
3123
3124	//- Share All, use guest account
3125	if(st_samba_mode==0){
3126		buffer_copy_string(con->router_user, "guest");
3127		account_right = 1;
3128		return account_right;
3129	}
3130
3131
3132	char * pch;
3133	pch = strtok(nvram_acc_list, "<>");
3134
3135	while(pch!=NULL){
3136		char *name;
3137		char *pass;
3138		int len;
3139
3140		//- User Name
3141		len = strlen(pch);
3142		name = (char*)malloc(len+1);
3143		strncpy(name, pch, len);
3144		name[len] = '\0';
3145
3146		//- User Password
3147		pch = strtok(NULL,"<>");
3148		len = strlen(pch);
3149		pass = (char*)malloc(len+1);
3150		strncpy(pass, pch, len);
3151		pass[len] = '\0';
3152
3153		if( strcmp(username, name) == 0 &&
3154		    strcmp(password, pass) == 0 ){
3155
3156			//Cdbg(1, "22222222222 name = %s, pass=%s, right=%d", username, password, right);
3157
3158			int len2;
3159			char  *pch2, *name2;
3160			pch2 = strtok(nvram_acc_webdavproxy, "<>");
3161
3162			while(pch2!=NULL){
3163				//- User Name
3164				len2 = strlen(pch2);
3165				name2 = (char*)malloc(len2+1);
3166				strncpy(name2, pch2, len2);
3167				name2[len2] = '\0';
3168
3169				//- User Right
3170				pch2 = strtok(NULL,"<>");
3171				account_right = atoi(pch2);
3172
3173				if( strcmp(username, name2) == 0 ){
3174					free(name2);
3175
3176					if(con->smb_info)
3177						con->smb_info->auth_right = account_right;
3178
3179					//- Copy user name to router_user
3180					buffer_copy_string(con->router_user, username);
3181
3182					found_account = 1;
3183
3184					break;
3185				}
3186
3187				free(name2);
3188				pch2 = strtok(NULL,"<>");
3189			}
3190
3191			free(name);
3192			free(pass);
3193
3194			if(found_account==1)
3195				break;
3196		}
3197
3198		free(name);
3199		free(pass);
3200
3201		pch = strtok(NULL,"<>");
3202	}
3203
3204	free(nvram_acc_list);
3205	free(nvram_acc_webdavproxy);
3206
3207	return account_right;
3208}
3209#endif
3210
3211int is_jffs_supported(void){
3212
3213#ifdef EMBEDDED_EANBLE
3214	if(dir_exist("/jffs/"))
3215		return 1;
3216#else
3217	if(dir_exist("/tmp/"))
3218		return 1;
3219#endif
3220
3221	return 0;
3222}
3223
3224//- 20121108 JerryLin add for router to router sync use.
3225void process_share_link_for_router_sync_use(){
3226
3227	int expire = 0;
3228	int toshare = 2;
3229
3230#if EMBEDDED_EANBLE
3231	char* username = nvram_get_http_username();
3232	char* password = nvram_get_http_passwd();
3233	char* a = nvram_get_share_link_param();
3234
3235	if(a==NULL)
3236		return;
3237
3238	int len = strlen(a) + 1;
3239	char* str_sharelink_param = (char*)malloc(len);
3240	memset(str_sharelink_param, '\0', len);
3241	memcpy(str_sharelink_param, a, len);
3242	#ifdef APP_IPKG
3243	free(a);
3244	#endif
3245	Cdbg(1, "str_sharelink_param=%s", str_sharelink_param);
3246
3247#else
3248	char username[20] = "admin";
3249	char password[20] = "admin";
3250	//char str_sharelink_param[100] = "/usbdisk/a1/>folder1</usbdisk/a2/>folder2";
3251	char str_sharelink_param[100] = "delete>AICLOUD306106790";
3252#endif
3253
3254	char auth[100]="\0";
3255	sprintf(auth, "%s:%s", username, password);
3256	char* base64_auth = ldb_base64_encode(auth, strlen(auth));
3257#ifdef APP_IPKG
3258	#if EMBEDDED_EANBLE
3259	free(username);
3260	free(password);
3261	#endif
3262#endif
3263	buffer* return_sharelink = buffer_init();
3264	buffer_reset(return_sharelink);
3265
3266	char *pch, *pch2, *saveptr=NULL, *saveptr2=NULL;
3267	pch = strtok_r(str_sharelink_param, "<", &saveptr);
3268
3269	while(pch!=NULL){
3270		char* tmp = strdup(pch);
3271		pch2 = strtok_r(tmp, ">", &saveptr2);
3272
3273		while(pch2!=NULL){
3274
3275			if(strcmp(pch2, "delete") == 0 ){
3276
3277				int b_save_arpping_list = 0;
3278				char* short_link = strtok_r(NULL, ">", &saveptr2);
3279
3280				if(short_link!=NULL){
3281					share_link_info_t* c;
3282					for (c = share_link_info_list; c; c = c->next) {
3283
3284						if(c->toshare != 2)
3285							continue;
3286
3287						if(buffer_is_equal_string(c->shortpath, short_link, strlen(short_link))){
3288							DLIST_REMOVE(share_link_info_list, c);
3289							b_save_arpping_list = 1;
3290							break;
3291						}
3292					}
3293
3294					if(b_save_arpping_list)
3295						save_sharelink_list();
3296				}
3297			}
3298			else{
3299				char* filename = strtok_r(NULL, ">", &saveptr2);
3300				if(filename!=NULL){
3301					share_link_info_t *share_link_info;
3302					share_link_info = (share_link_info_t *)calloc(1, sizeof(share_link_info_t));
3303
3304					char share_link[1024];
3305					struct timeval tv;
3306					unsigned long long now_utime;
3307					gettimeofday(&tv,NULL);
3308					now_utime = tv.tv_sec * 1000000 + tv.tv_usec;
3309					sprintf( share_link, "AICLOUD%d", abs(now_utime));
3310
3311					buffer_append_string(return_sharelink, share_link);
3312					buffer_append_string(return_sharelink, ">");
3313
3314					share_link_info->shortpath = buffer_init();
3315					buffer_copy_string(share_link_info->shortpath, share_link);
3316
3317					share_link_info->realpath = buffer_init();
3318					buffer_copy_string(share_link_info->realpath, pch2);
3319
3320					share_link_info->filename = buffer_init();
3321					buffer_copy_string(share_link_info->filename, filename);
3322
3323					share_link_info->auth = buffer_init();
3324					buffer_copy_string(share_link_info->auth, base64_auth);
3325
3326					share_link_info->createtime = time(NULL);
3327					share_link_info->expiretime = 0;
3328					share_link_info->toshare = toshare;
3329
3330					DLIST_ADD(share_link_info_list, share_link_info);
3331				}
3332			}
3333
3334			//- Next
3335			pch2 = strtok_r(NULL, ">", &saveptr2);
3336		}
3337
3338		if(tmp!=NULL)
3339			free(tmp);
3340
3341		//- Next
3342		pch = strtok_r(NULL, "<", &saveptr);
3343	}
3344
3345	save_sharelink_list();
3346
3347#if EMBEDDED_EANBLE
3348	nvram_set_share_link_result(return_sharelink->ptr);
3349	free(str_sharelink_param);
3350#endif
3351
3352	Cdbg(DBE,"process_share_link_for_router_sync_use...return_sharelink=%s", return_sharelink->ptr);
3353
3354	buffer_free(return_sharelink);
3355}
3356
3357static const char base64_xlat[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3358int base64_decode2(const char *in, unsigned char *out, int inlen)
3359{
3360    char *p;
3361    int n;
3362    unsigned long x;
3363    unsigned char *o;
3364    char c;
3365    o = out;
3366    n = 0;
3367    x = 0;
3368    while (inlen-- > 0) {
3369        if (*in == '=') break;
3370        if ((p = strchr(base64_xlat, c = *in++)) == NULL) {
3371//          printf("ignored - %x %c\n", c, c);
3372            continue;   // note: invalid characters are just ignored
3373        }
3374        x = (x << 6) | (p - base64_xlat);
3375        if (++n == 4) {
3376            *out++ = x >> 16;
3377            *out++ = (x >> 8) & 0xFF;
3378            *out++ = x & 0xFF;
3379            n = 0;
3380            x = 0;
3381        }
3382    }
3383    if (n == 3) {
3384        *out++ = x >> 10;
3385        *out++ = (x >> 2) & 0xFF;
3386    }
3387    else if (n == 2) {
3388        *out++ = x >> 4;
3389    }
3390    return out - o;
3391}
3392
3393/* md5sum:
3394 * Concatenates a series of strings together then generates an md5
3395 * message digest. Writes the result directly into 'output', which
3396 * MUST be large enough to accept the result. (Size ==
3397 * 128 + null terminator.)
3398 */
3399char secret[100] = "804b51d14d840d6e";
3400
3401/* sprint_hex:
3402 * print a long hex value into a string buffer. This function will
3403 * write 'len' bytes of data from 'char_buf' into 2*len bytes of space
3404 * in 'output'. (Each hex value is 4 bytes.) Space in output must be
3405 * pre-allocated. */
3406void sprint_hex(char* output, unsigned char* char_buf, int len)
3407{
3408	int i;
3409	for (i=0; i < len; i++) {
3410		sprintf(output + i*2, "%02x", char_buf[i]);
3411	}
3412}
3413
3414void md5sum(char* output, int counter, ...)
3415{
3416	va_list argp;
3417	unsigned char temp[MD5_DIGEST_LENGTH];
3418	char* md5_string;
3419	int full_len;
3420	int i, str_len;
3421	int buffer_size = 10;
3422
3423	md5_string = (char*)malloc(buffer_size);
3424	md5_string[0] = '\0';
3425
3426	full_len = 0;
3427	va_start(argp, secret);
3428	for (i = 0; i < counter; i++) {
3429		char* string = va_arg(argp, char*);
3430		int len = strlen(string);
3431
3432		/* If the buffer is not large enough, expand until it is. */
3433		while (len + full_len > buffer_size - 1) {
3434			buffer_size += buffer_size;
3435			md5_string = realloc(md5_string, buffer_size);
3436		}
3437
3438		strncat(md5_string, string, len);
3439
3440		full_len += len;
3441		md5_string[full_len] = '\0';
3442	}
3443	va_end(argp);
3444
3445	str_len = strlen(md5_string);
3446	MD5((const unsigned char*)md5_string, (unsigned int)str_len, temp);
3447
3448	free(md5_string);
3449
3450	sprint_hex(output, temp, MD5_DIGEST_LENGTH);
3451	output[129] = '\0';
3452}
3453
3454int check_skip_folder_name(char* foldername){
3455	if ( strcmp(foldername, "minidlna")==0 ||
3456		 strcmp(foldername, "asusware")==0 ||
3457		 strcmp(foldername, "asusware.big")==0 ||
3458		 strcmp(foldername, "asusware.mipsbig")==0 ||
3459		 strcmp(foldername, "asusware.arm")==0 ||
3460		 strcmp(foldername, "$RECYCLE.BIN")==0 ||
3461		 strcmp(foldername, "System Volume Information")==0 ) {
3462		 return 1;
3463	}
3464
3465	if ( prefix_is(foldername, "ntfsck")==1 )
3466		return 1;
3467
3468	return 0;
3469}
3470
3471int prefix_is(char* source, char* prefix){
3472	if(source==NULL||prefix==NULL)
3473		return -1;
3474
3475	int index = strstr(source, prefix) - source;
3476
3477	return (index==0) ? 1 : -1;
3478}
3479#if 0
3480int is_utf8_file(const char* file){
3481	FILE* fp;
3482	unsigned char header[5];
3483	int ret = 0;
3484	if((fp = fopen(file, "rb")) != NULL){
3485		fgets(header, 5, fp);
3486		if (header[0] == 0xEF && header[1] == 0xBB && header[2] == 0xBF){
3487			ret = 1;
3488		}
3489
3490		fclose(fp);
3491	}
3492
3493	return ret;
3494}
3495
3496//- Unicode -> ANSI
3497char* w2m(const wchar_t* wcs)
3498{
3499      int len;
3500      char* buf;
3501      len =wcstombs(NULL,wcs,0);
3502      if (len == 0)
3503          return NULL;
3504      buf = (char *)malloc(sizeof(char)*(len+1));
3505      memset(buf, 0, sizeof(char) *(len+1));
3506      len =wcstombs(buf,wcs,len+1);
3507      return buf;
3508}
3509
3510int ansiToWCHAR(wchar_t* out, int outsize, const char* in, int insize, const char* codepage)
3511{
3512    if(outsize > 0 && insize > 0 && out && in && setlocale(LC_ALL, codepage))
3513    {
3514    	Cdbg(1, "ansiToWCHAR, in=%s", in);
3515        int size = mbstowcs(out,in,outsize);
3516        if(size < outsize - 1){out[size]=0;out[size+1]=0;}
3517        return size;
3518    }
3519    return 0;
3520}
3521
3522//- ANSI -> Unicode
3523wchar_t* m2w(const char* mbs)
3524{
3525    int len;
3526    wchar_t* buf;
3527	setlocale(LC_ALL, "en_ZW.utf8");
3528
3529    len = mbstowcs(0,mbs,0);
3530    if (len <= 0){
3531		return NULL;
3532 	}
3533	Cdbg(1, "mbstowcs len=%d", len);
3534
3535#if 0
3536	buf = (wchar_t *)malloc(sizeof(wchar_t)*(len/2 + 1));
3537	memset(buf, 0, sizeof(wchar_t)*(len/2 + 1));
3538    len = mbstowcs(buf, mbs, len/2+1);
3539#else
3540	buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
3541    memset(buf, 0, sizeof(wchar_t) *(len+1));
3542    len = mbstowcs(buf,mbs,len+1);
3543#endif
3544	Cdbg(1, "len=%d, buf=%s, mbs=%s", len, buf, mbs);
3545    return buf;
3546}
3547
3548int enc_unicode_to_utf8_one(unsigned long unic, unsigned char *pOutput,
3549        int outSize)
3550{
3551    //assert(pOutput != NULL);
3552    //assert(outSize >= 6);
3553
3554    if ( unic <= 0x0000007F )
3555    {
3556        // * U-00000000 - U-0000007F:  0xxxxxxx
3557        *pOutput     = (unic & 0x7F);
3558        return 1;
3559    }
3560    else if ( unic >= 0x00000080 && unic <= 0x000007FF )
3561    {
3562        // * U-00000080 - U-000007FF:  110xxxxx 10xxxxxx
3563        *(pOutput+1) = (unic & 0x3F) | 0x80;
3564        *pOutput     = ((unic >> 6) & 0x1F) | 0xC0;
3565        return 2;
3566    }
3567    else if ( unic >= 0x00000800 && unic <= 0x0000FFFF )
3568    {
3569        // * U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx
3570        *(pOutput+2) = (unic & 0x3F) | 0x80;
3571        *(pOutput+1) = ((unic >> 6) & 0x3F) | 0x80;
3572        *pOutput     = ((unic >> 12) & 0x0F) | 0xE0;
3573        return 3;
3574    }
3575    else if ( unic >= 0x00010000 && unic <= 0x001FFFFF )
3576    {
3577        // * U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
3578        *(pOutput+3) = (unic & 0x3F) | 0x80;
3579        *(pOutput+2) = ((unic >> 6) & 0x3F) | 0x80;
3580        *(pOutput+1) = ((unic >> 12) & 0x3F) | 0x80;
3581        *pOutput     = ((unic >> 18) & 0x07) | 0xF0;
3582        return 4;
3583    }
3584    else if ( unic >= 0x00200000 && unic <= 0x03FFFFFF )
3585    {
3586        // * U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
3587        *(pOutput+4) = (unic & 0x3F) | 0x80;
3588        *(pOutput+3) = ((unic >> 6) & 0x3F) | 0x80;
3589        *(pOutput+2) = ((unic >> 12) & 0x3F) | 0x80;
3590        *(pOutput+1) = ((unic >> 18) & 0x3F) | 0x80;
3591        *pOutput     = ((unic >> 24) & 0x03) | 0xF8;
3592        return 5;
3593    }
3594    else if ( unic >= 0x04000000 && unic <= 0x7FFFFFFF )
3595    {
3596        // * U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
3597        *(pOutput+5) = (unic & 0x3F) | 0x80;
3598        *(pOutput+4) = ((unic >> 6) & 0x3F) | 0x80;
3599        *(pOutput+3) = ((unic >> 12) & 0x3F) | 0x80;
3600        *(pOutput+2) = ((unic >> 18) & 0x3F) | 0x80;
3601        *(pOutput+1) = ((unic >> 24) & 0x3F) | 0x80;
3602        *pOutput     = ((unic >> 30) & 0x01) | 0xFC;
3603        return 6;
3604    }
3605
3606    return 0;
3607}
3608
3609
3610int do_iconv(const char* to_ces, const char* from_ces,
3611	 char *inbuf,  size_t inbytesleft,
3612	 char *outbuf_orig, size_t outbytesleft_orig)
3613{
3614#ifdef HAVE_ICONV_H
3615	size_t rc;
3616	int ret = 1;
3617
3618	size_t outbytesleft = outbytesleft_orig - 1;
3619	char* outbuf = outbuf_orig;
3620
3621	iconv_t cd  = iconv_open(to_ces, from_ces);
3622
3623	if(cd == (iconv_t)-1)
3624	{
3625		return 0;
3626	}
3627	rc = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
3628	//Cdbg(1, "outbuf=%s", outbuf);
3629	if(rc == (size_t)-1)
3630	{
3631		Cdbg(1, "fail");
3632		ret = 0;
3633		/*
3634		if(errno == E2BIG)
3635		{
3636			ret = 0;
3637		}
3638		else
3639		{
3640			ret = 0;
3641			memset(outbuf_orig, '\0', outbytesleft_orig);
3642		}
3643		*/
3644	}
3645	iconv_close(cd);
3646
3647	return ret;
3648#else // HAVE_ICONV_H
3649	return 0;
3650#endif // HAVE_ICONV_H
3651}
3652
3653int enc_get_utf8_size(unsigned char c)
3654{
3655    unsigned char t = 0x80;
3656    unsigned char r = c;
3657    int count = 0;
3658
3659    while ( r & t )
3660    {
3661        r = r << 1;
3662        count++;
3663    }
3664
3665    return count;
3666}
3667
3668int enc_utf8_to_unicode_one(const unsigned char* pInput, unsigned long *Unic)
3669{
3670    assert(pInput != NULL && Unic != NULL);
3671
3672    char b1, b2, b3, b4, b5, b6;
3673
3674    *Unic = 0x0;
3675    int utfbytes = enc_get_utf8_size(*pInput);
3676    unsigned char *pOutput = (unsigned char *) Unic;
3677
3678    switch ( utfbytes )
3679    {
3680        case 0:
3681            *pOutput     = *pInput;
3682            utfbytes    += 1;
3683            break;
3684        case 2:
3685            b1 = *pInput;
3686            b2 = *(pInput + 1);
3687            if ( (b2 & 0xE0) != 0x80 )
3688                return 0;
3689            *pOutput     = (b1 << 6) + (b2 & 0x3F);
3690            *(pOutput+1) = (b1 >> 2) & 0x07;
3691            break;
3692        case 3:
3693            b1 = *pInput;
3694            b2 = *(pInput + 1);
3695            b3 = *(pInput + 2);
3696            if ( ((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80) )
3697                return 0;
3698            *pOutput     = (b2 << 6) + (b3 & 0x3F);
3699            *(pOutput+1) = (b1 << 4) + ((b2 >> 2) & 0x0F);
3700            break;
3701        case 4:
3702            b1 = *pInput;
3703            b2 = *(pInput + 1);
3704            b3 = *(pInput + 2);
3705            b4 = *(pInput + 3);
3706            if ( ((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80)
3707                    || ((b4 & 0xC0) != 0x80) )
3708                return 0;
3709            *pOutput     = (b3 << 6) + (b4 & 0x3F);
3710            *(pOutput+1) = (b2 << 4) + ((b3 >> 2) & 0x0F);
3711            *(pOutput+2) = ((b1 << 2) & 0x1C)  + ((b2 >> 4) & 0x03);
3712            break;
3713        case 5:
3714            b1 = *pInput;
3715            b2 = *(pInput + 1);
3716            b3 = *(pInput + 2);
3717            b4 = *(pInput + 3);
3718            b5 = *(pInput + 4);
3719            if ( ((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80)
3720                    || ((b4 & 0xC0) != 0x80) || ((b5 & 0xC0) != 0x80) )
3721                return 0;
3722            *pOutput     = (b4 << 6) + (b5 & 0x3F);
3723            *(pOutput+1) = (b3 << 4) + ((b4 >> 2) & 0x0F);
3724            *(pOutput+2) = (b2 << 2) + ((b3 >> 4) & 0x03);
3725            *(pOutput+3) = (b1 << 6);
3726            break;
3727        case 6:
3728            b1 = *pInput;
3729            b2 = *(pInput + 1);
3730            b3 = *(pInput + 2);
3731            b4 = *(pInput + 3);
3732            b5 = *(pInput + 4);
3733            b6 = *(pInput + 5);
3734            if ( ((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80)
3735                    || ((b4 & 0xC0) != 0x80) || ((b5 & 0xC0) != 0x80)
3736                    || ((b6 & 0xC0) != 0x80) )
3737                return 0;
3738            *pOutput     = (b5 << 6) + (b6 & 0x3F);
3739            *(pOutput+1) = (b5 << 4) + ((b6 >> 2) & 0x0F);
3740            *(pOutput+2) = (b3 << 2) + ((b4 >> 4) & 0x03);
3741            *(pOutput+3) = ((b1 << 6) & 0x40) + (b2 & 0x3F);
3742            break;
3743        default:
3744            return 0;
3745            break;
3746    }
3747
3748    return utfbytes;
3749}
3750
3751int enc_utf8_to_unicode(const unsigned char* pInput, int nMembIn,unsigned long* pOutput, int* nMembOut)
3752{
3753    assert(pInput != NULL && pOutput != NULL);
3754    assert(*nMembOut >= 1);
3755
3756    int i, ret, outSize;
3757    const unsigned char *pIn     = pInput;
3758    unsigned long       *pOutCur = pOutput;
3759
3760    outSize = *nMembOut;
3761    for ( i = 0; i < nMembIn; )
3762    {
3763        if ( pOutCur - pOutput >= outSize )
3764        {
3765            *nMembOut = pOutCur - pOutput;
3766            return 2; // ?�X��?����
3767        }
3768
3769        ret = enc_utf8_to_unicode_one(pIn, pOutCur);
3770        if ( ret == 0 )
3771        {
3772            *nMembOut = pOutCur - pOutput;
3773            return 0; // ?�J���r��??���OUTF8
3774        }
3775
3776        i    += ret;
3777        pIn  += ret;
3778        pOutCur += 1;
3779    }
3780
3781    *nMembOut = pOutCur - pOutput;
3782    return 1;
3783}
3784
3785int enc_utf8_to_unicode_str(const unsigned char *pInput,unsigned long *pOutput, int *nMembOut)
3786{
3787    assert(pInput != NULL && pOutput != NULL);
3788    assert(*nMembOut >= 1);
3789
3790    return enc_utf8_to_unicode(pInput, strlen((const char *)pInput),
3791            pOutput, nMembOut);
3792}
3793
3794int enc_unicode_to_utf8(const unsigned long *pInput, int nMembIn, unsigned char *pOutput, int *nMembOut)
3795{
3796    assert(pInput != NULL && pOutput != NULL );
3797    assert(*nMembOut >= 6);
3798
3799    int i, ret, outSize, resOutSize;
3800    const unsigned long *pIn     = pInput;
3801    unsigned char       *pOutCur = pOutput;
3802
3803    outSize = *nMembOut;
3804    for ( i = 0; i < nMembIn; )
3805    {
3806        resOutSize = outSize - (pOutCur - pOutput);
3807        if ( resOutSize < 6 )
3808        {
3809            *nMembOut = pOutCur - pOutput;
3810            return 2;
3811        }
3812
3813        ret = enc_unicode_to_utf8_one(*pIn, pOutCur, resOutSize);
3814        if ( ret == 0 )
3815        {
3816            *nMembOut = pOutCur - pOutput;
3817            return 0;
3818        }
3819
3820        i   += 1;
3821        pIn += 1;
3822        pOutCur += ret;
3823    }
3824
3825    *nMembOut = pOutCur - pOutput;
3826    return 1;
3827}
3828
3829int enc_unicode_to_utf8_str(const unsigned long *pInput, unsigned char *pOutput, int *nMembOut)
3830{
3831    if(pInput == NULL || pOutput == NULL )
3832		return 0;
3833
3834    if(*nMembOut < 6)
3835		return 0;
3836
3837    int i, ret, outSize, resOutSize;
3838    const unsigned long *pIn     = pInput;
3839    unsigned char       *pOutCur = pOutput;
3840
3841    outSize = *nMembOut;
3842    for ( ; *pIn != 0; )
3843    {
3844        resOutSize = outSize - (pOutCur - pOutput);
3845        if ( resOutSize < 6 )
3846        {
3847            *nMembOut = pOutCur - pOutput;
3848            return 2;
3849        }
3850
3851        ret = enc_unicode_to_utf8_one(*pIn, pOutCur, resOutSize);
3852        if ( ret == 0 )
3853        {
3854            *nMembOut = pOutCur - pOutput;
3855            return 0;
3856        }
3857
3858        i   += 1;
3859        pIn += 1;
3860        pOutCur += ret;
3861    }
3862
3863    *nMembOut = pOutCur - pOutput;
3864    return 1;
3865}
3866#endif
3867
3868#if EMBEDDED_EANBLE
3869
3870int get_aicloud_var_file_name(const char *const account, const char *const path, char **file_name){
3871	int len;
3872	char *var_file;
3873	char ascii_user[64];
3874
3875	if(path == NULL)
3876		return -1;
3877
3878	len = strlen(path)+strlen("/.__aicloud__var.txt");
3879	if(account != NULL){
3880		memset(ascii_user, 0, 64);
3881		char_to_ascii_safe(ascii_user, account, 64);
3882
3883		len += strlen(ascii_user);
3884	}
3885	*file_name = (char *)malloc(sizeof(char)*(len+1));
3886	if(*file_name == NULL)
3887		return -1;
3888
3889	var_file = *file_name;
3890	if(account != NULL)
3891		sprintf(var_file, "%s/.__aicloud_%s_var.txt", path, ascii_user);
3892	else
3893		sprintf(var_file, "%s/.__aicloud_var.txt", path);
3894	var_file[len] = 0;
3895
3896	return 0;
3897}
3898
3899int initial_aicloud_var_file(const char *const account, const char *const mount_path) {
3900	FILE *fp;
3901	char *var_file;
3902	int result, i;
3903	int sh_num;
3904	char **folder_list;
3905	int aicloud_right = 0;
3906
3907	if (mount_path == NULL || strlen(mount_path) <= 0) {
3908		Cdbg(DBE, "No input, mount_path");
3909		return -1;
3910	}
3911
3912	// 1. get the folder number and folder_list
3913	//result = get_folder_list(mount_path, &sh_num, &folder_list);
3914	result = get_all_folder(mount_path, &sh_num, &folder_list);
3915
3916	// 2. get the var file
3917	if(get_aicloud_var_file_name(account, mount_path, &var_file)){
3918		Cdbg(DBE, "Can't malloc \"var_file\".");
3919		free_2_dimension_list(&sh_num, &folder_list);
3920		return -1;
3921	}
3922
3923	// 4. write the default content in the var file
3924	if ((fp = fopen(var_file, "w")) == NULL) {
3925		Cdbg(DBE, "Can't create the var file, \"%s\".", var_file);
3926		free_2_dimension_list(&sh_num, &folder_list);
3927		free(var_file);
3928		return -1;
3929	}
3930
3931	for (i = -1; i < sh_num; ++i) {
3932		fprintf(fp, "*");
3933
3934		if(i != -1)
3935			fprintf(fp, "%s", folder_list[i]);
3936
3937		fprintf(fp, "=%d\n", aicloud_right);
3938	}
3939
3940	fclose(fp);
3941	free_2_dimension_list(&sh_num, &folder_list);
3942
3943	// 5. set the check target of file.
3944	set_file_integrity(var_file);
3945	free(var_file);
3946
3947	return 0;
3948}
3949
3950int get_aicloud_permission(const char *const account,
3951								const char *const mount_path,
3952								const char *const folder) {
3953	char *var_file, *var_info;
3954	char *target, *follow_info;
3955	int len, result;
3956	char *f = (char*) folder;
3957
3958	Cdbg(DBE, "get_aicloud_permission: %s, %s, %s.", account, mount_path, folder);
3959
3960	// 1. get the aicloud var file
3961	if(get_aicloud_var_file_name(account, mount_path, &var_file)){
3962		Cdbg(DBE, "Can't malloc \"var_file\".");
3963		return -1;
3964	}
3965
3966	Cdbg(DBE, "var_file: %s.", var_file);
3967
3968	// 2. check the file integrity.
3969	if(!check_file_integrity(var_file)){
3970		Cdbg(DBE, "Fail to check the file: %s.", var_file);
3971		if(initial_var_file(account, mount_path) != 0){
3972			Cdbg(DBE, "Can't initial \"%s\"'s file in %s.", account, mount_path);
3973			free(var_file);
3974			return -1;
3975		}
3976	}
3977
3978	// 3. get the content of the var_file of the account
3979	var_info = read_whole_file(var_file);
3980	if (var_info == NULL) {
3981		Cdbg(DBE, "get_permission: \"%s\" isn't existed or there's no content.", var_file);
3982		free(var_file);
3983		return -1;
3984	}
3985	free(var_file);
3986
3987	// 4. get the target in the content
3988retry_get_permission:
3989	if(f == NULL)
3990		len = strlen("*=");
3991	else
3992		len = strlen("*")+strlen(f)+strlen("=");
3993	target = (char *)malloc(sizeof(char)*(len+1));
3994	if (target == NULL) {
3995		Cdbg(DBE, "Can't allocate \"target\".");
3996		free(var_info);
3997		return -1;
3998	}
3999	if(f == NULL)
4000		strcpy(target, "*=");
4001	else
4002		sprintf(target, "*%s=", f);
4003	target[len] = 0;
4004
4005	follow_info = upper_strstr(var_info, target);
4006	free(target);
4007	if (follow_info == NULL) {
4008		if(account == NULL)
4009			Cdbg(DBE, "No right about \"%s\" with the share mode.", f? f:"Pool");
4010		else
4011			Cdbg(DBE, "No right about \"%s\" with \"%s\".", f? f:"Pool", account);
4012
4013		if (f == NULL) {
4014			free(var_info);
4015			return -1;
4016		} else {
4017			f = NULL;
4018			goto retry_get_permission;
4019		}
4020	}
4021
4022	follow_info += len;
4023
4024	if (follow_info[1] != '\n') {
4025		if(account == NULL)
4026			Cdbg(DBE, "The var info is incorrect.\nPlease reset the var file of the share mode.");
4027		else
4028			Cdbg(DBE, "The var info is incorrect.\nPlease reset the var file of \"%s\".", account);
4029
4030		free(var_info);
4031		return -1;
4032	}
4033
4034	// 5. get the right of folder
4035	result = follow_info[0]-'0';
4036
4037	free(var_info);
4038
4039	if (result < 0 || result > 3) {
4040		if(account == NULL)
4041			Cdbg(DBE, "The var info is incorrect.\nPlease reset the var file of the share mode.");
4042		else
4043			Cdbg(DBE, "The var info is incorrect.\nPlease reset the var file of \"%s\".", account);
4044		return -1;
4045	}
4046
4047	return result;
4048}
4049
4050int set_aicloud_permission(const char *const account,
4051						  const char *const mount_path,
4052						  const char *const folder,
4053						  const int flag) {
4054	FILE *fp;
4055	char *var_file, *var_info;
4056	char *target, *follow_info;
4057	int len;
4058
4059	if (flag < 0 || flag > 3) {
4060		Cdbg(DBE, "correct Rights is 0, 1, 2, 3.");
4061		return -1;
4062	}
4063
4064	// 1. get the var file
4065	if(get_aicloud_var_file_name(account, mount_path, &var_file)){
4066		Cdbg(DBE, "Can't malloc \"var_file\".");
4067		return -1;
4068	}
4069
4070	if(!check_if_file_exist(var_file)){
4071		if(initial_aicloud_var_file(account, mount_path)!=0){
4072			Cdbg(DBE, "Fail to check the folder list.");
4073			return -1;
4074		}
4075	}
4076
4077
4078	// 2. check the file integrity.
4079	if(!check_file_integrity(var_file)){
4080		Cdbg(DBE, "Fail to check the file: %s.", var_file);
4081		if(initial_var_file(account, mount_path) != 0){
4082			Cdbg(DBE, "Can't initial \"%s\"'s file in %s.", account, mount_path);
4083			free(var_file);
4084			return -1;
4085		}
4086	}
4087
4088	// 3. get the content of the var_file of the account
4089	var_info = read_whole_file(var_file);
4090	if (var_info == NULL) {
4091		initial_aicloud_var_file(account, mount_path);
4092		sleep(1);
4093		var_info = read_whole_file(var_file);
4094		if (var_info == NULL) {
4095			Cdbg(DBE, "set_permission: \"%s\" isn't existed or there's no content.", var_file);
4096			free(var_file);
4097			return -1;
4098		}
4099	}
4100
4101	// 4. get the target in the content
4102	if(folder == NULL)
4103		len = strlen("*=");
4104	else
4105		len = strlen("*")+strlen(folder)+strlen("=");
4106	target = (char *)malloc(sizeof(char)*(len+1));
4107	if (target == NULL) {
4108		Cdbg(DBE, "Can't allocate \"target\".");
4109		free(var_file);
4110		free(var_info);
4111
4112		return -1;
4113	}
4114	if(folder == NULL)
4115		strcpy(target, "*=");
4116	else
4117		sprintf(target, "*%s=", folder);
4118	target[len] = 0;
4119
4120	// 5. judge if the target is in the var file.
4121	follow_info = upper_strstr(var_info, target);
4122	if (follow_info == NULL) {
4123		if(account == NULL)
4124			Cdbg(DBE, "No right about \"%s\" with the share mode.", (folder == NULL?"Pool":folder));
4125		else
4126			Cdbg(DBE, "No right about \"%s\" with \"%s\".", (folder == NULL?"Pool":folder), account);
4127		free(var_info);
4128
4129		fp = fopen(var_file, "a+");
4130		if (fp == NULL) {
4131			Cdbg(DBE, "1. Can't rewrite the file, \"%s\".", var_file);
4132			free(var_file);
4133			return -1;
4134		}
4135		free(var_file);
4136
4137		fprintf(fp, "%s", target);
4138		free(target);
4139
4140		fprintf(fp, "%d\n", 0, 0, flag);
4141
4142		fclose(fp);
4143		return 0;
4144	}
4145	free(target);
4146
4147	follow_info += len;
4148	if (follow_info[1] != '\n') {
4149		if(account == NULL)
4150			Cdbg(DBE, "The var info is incorrect.\nPlease reset the var file of the share mode.");
4151		else
4152			Cdbg(DBE, "The var info is incorrect.\nPlease reset the var file of \"%s\".", account);
4153		free(var_file);
4154		free(var_info);
4155		return -1;
4156	}
4157
4158	if(follow_info[0] == '0'+flag){
4159		Cdbg(DBE, "The aicloud right of \"%s\" is the same.", folder);
4160		free(var_file);
4161		free(var_info);
4162		return 0;
4163	}
4164
4165	follow_info[0] = '0'+flag;
4166
4167	// 7. rewrite the var file.
4168	fp = fopen(var_file, "w");
4169	if (fp == NULL) {
4170		Cdbg(DBE, "2. Can't rewrite the file, \"%s\".", var_file);
4171		free(var_file);
4172		free(var_info);
4173		return -1;
4174	}
4175	fprintf(fp, "%s", var_info);
4176	fclose(fp);
4177	free(var_info);
4178
4179	return 0;
4180}
4181
4182#endif
4183
4184#if 0
4185int del_aicloud_account(const char *account){
4186	if(account==NULL)
4187		return -1;
4188
4189	char *err;
4190	char sql_query[2048] = "\0";
4191	sqlite3 *sql_aicloud;
4192	char **result;
4193	int rows;
4194	int column_count;
4195	char* aicloud_db_file_path = get_aicloud_db_file_path();
4196
4197	if (SQLITE_OK != sqlite3_open(aicloud_db_file_path, &(sql_aicloud))) {
4198		return -1;
4199	}
4200
4201	sprintf(sql_query, "DELETE FROM account_info WHERE username='%s'", account );
4202
4203	if (SQLITE_OK != sqlite3_exec(sql_aicloud, sql_query , NULL, NULL, &err)) {
4204		sqlite3_free(err);
4205		sqlite3_close(sql_aicloud);
4206		return -1;
4207	}
4208
4209	if (sql_aicloud) {
4210		sqlite3_close(sql_aicloud);
4211	}
4212
4213#if EMBEDDED_EANBLE
4214
4215	disk_info_t *disk_list, *follow_disk;
4216	partition_info_t *follow_partition;
4217	char *var_file, *ptr;
4218	DIR *opened_dir;
4219	struct dirent *dp;
4220	int len;
4221
4222	disk_list = read_disk_data();
4223	if(disk_list != NULL){
4224
4225		for(follow_disk = disk_list; follow_disk != NULL; follow_disk = follow_disk->next){
4226			for(follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
4227				if(follow_partition->mount_point == NULL)
4228					continue;
4229
4230				if(get_aicloud_var_file_name(account, follow_partition->mount_point, &var_file)){
4231					//free_disk_data(&disk_list);
4232					continue;
4233				}
4234
4235				if((ptr = strrchr(var_file, '/')) == NULL){
4236					//free_disk_data(&disk_list);
4237					free(var_file);
4238					continue;
4239				}
4240
4241				if((opened_dir = opendir(follow_partition->mount_point)) == NULL){
4242					//free_disk_data(&disk_list);
4243					free(var_file);
4244					continue;
4245				}
4246
4247				++ptr;
4248
4249				len = strlen(ptr);
4250				while((dp = readdir(opened_dir)) != NULL){
4251					char test_path[PATH_MAX];
4252
4253					if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
4254						continue;
4255
4256					if(strncmp(dp->d_name, ptr, len))
4257						continue;
4258
4259					memset(test_path, 0, PATH_MAX);
4260					sprintf(test_path, "%s/%s", follow_partition->mount_point, dp->d_name);
4261					Cdbg(1, "delete %s.", test_path);
4262
4263					delete_file_or_dir(test_path);
4264				}
4265				closedir(opened_dir);
4266
4267				free(var_file);
4268			}
4269		}
4270
4271		free_disk_data(&disk_list);
4272	}
4273#endif
4274
4275	return 0;
4276}
4277#endif
4278
4279
4280int is_connection_admin_permission(server* srv, connection* con){
4281	if(con==NULL || srv==NULL)
4282		return 0;
4283
4284	data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
4285	if(ds!=NULL){
4286		smb_info_t *c;
4287		for (c = srv->smb_srv_info_list; c; c = c->next) {
4288
4289			if( buffer_is_equal(c->user_agent, ds->value) &&
4290				buffer_is_equal(c->src_ip, con->dst_addr_buf) &&
4291				buffer_is_empty(c->server) ){
4292
4293				if( smbc_get_account_permission(c->username->ptr) == T_ADMIN ){
4294					return 1;
4295				}
4296
4297				break;
4298			}
4299
4300		}
4301	}
4302
4303	return 0;
4304}
4305
4306int parse_postdata_from_chunkqueue(server *srv, connection *con, chunkqueue *cq, char **ret_data) {
4307
4308	int res = -1;
4309
4310	chunk *c;
4311	char* result_data = NULL;
4312
4313	UNUSED(con);
4314
4315	for (c = cq->first; cq->bytes_out != cq->bytes_in; c = cq->first) {
4316		size_t weWant = cq->bytes_out - cq->bytes_in;
4317		size_t weHave;
4318
4319		switch(c->type) {
4320			case MEM_CHUNK:
4321				weHave = c->mem->used - 1 - c->offset;
4322
4323				if (weHave > weWant) weHave = weWant;
4324
4325				result_data = (char*)malloc(sizeof(char)*(weHave+1));
4326				memset(result_data, 0, sizeof(char)*(weHave+1));
4327				strcpy(result_data, c->mem->ptr + c->offset);
4328
4329				c->offset += weHave;
4330				cq->bytes_out += weHave;
4331
4332				res = 0;
4333
4334				break;
4335
4336			default:
4337				break;
4338		}
4339
4340		chunkqueue_remove_finished_chunks(cq);
4341	}
4342
4343	*ret_data = result_data;
4344
4345	return res;
4346}
4347
4348void read_aicloud_acc_list(){
4349
4350	char *nvram_aicloud_acc_list = NULL;
4351
4352#if EMBEDDED_EANBLE
4353	nvram_aicloud_acc_list = nvram_get_aicloud_acc_list();
4354#else
4355	nvram_aicloud_acc_list = read_whole_file("/tmp/aicloud_acc_list");
4356#endif
4357
4358	if(nvram_aicloud_acc_list==NULL){
4359		return;
4360	}
4361
4362	int len = strlen(nvram_aicloud_acc_list);
4363	char* aicloud_acc_list = malloc(len);
4364
4365	if(aicloud_acc_list==NULL){
4366		return;
4367	}
4368
4369	memset(aicloud_acc_list, '\0', len);
4370	strncpy(aicloud_acc_list, nvram_aicloud_acc_list, len);
4371
4372#if EMBEDDED_EANBLE
4373	#ifdef APP_IPKG
4374	if(nvram_aicloud_acc_list!=NULL)
4375		free(nvram_aicloud_acc_list);
4376	#endif
4377#else
4378	if(nvram_aicloud_acc_list!=NULL)
4379		free(nvram_aicloud_acc_list);
4380#endif
4381
4382	char * pch = strtok(aicloud_acc_list, "<>");
4383	while(pch!=NULL){
4384
4385		aicloud_acc_info_t *aicloud_acc_info;
4386		aicloud_acc_info = (aicloud_acc_info_t *)calloc(1, sizeof(aicloud_acc_info_t));
4387
4388		//- User Name
4389		aicloud_acc_info->username = buffer_init();
4390		buffer_copy_string_len(aicloud_acc_info->username, pch, strlen(pch));
4391		buffer_urldecode_path(aicloud_acc_info->username);
4392
4393		//- User Password
4394		pch = strtok(NULL,"<>");
4395		aicloud_acc_info->password = buffer_init();
4396		buffer_copy_string_len(aicloud_acc_info->password, pch, strlen(pch));
4397		buffer_urldecode_path(aicloud_acc_info->password);
4398
4399		//- next
4400		pch = strtok(NULL,"<>");
4401
4402		DLIST_ADD(aicloud_acc_info_list, aicloud_acc_info);
4403	}
4404
4405	free(aicloud_acc_list);
4406
4407}
4408
4409void save_aicloud_acc_list(){
4410	aicloud_acc_info_t* c;
4411
4412	buffer* aicloud_acc_list = buffer_init();
4413	buffer_copy_string(aicloud_acc_list, "");
4414
4415	for (c = aicloud_acc_info_list; c; c = c->next) {
4416
4417		if(!buffer_is_equal_string(aicloud_acc_list, "", 0))
4418			buffer_append_string(aicloud_acc_list, "<");
4419
4420		buffer_append_string_encoded(aicloud_acc_list, CONST_BUF_LEN(c->username), ENCODING_REL_URI);
4421		buffer_append_string(aicloud_acc_list, ">");
4422		buffer_append_string_encoded(aicloud_acc_list, CONST_BUF_LEN(c->password), ENCODING_REL_URI);
4423	}
4424
4425#if EMBEDDED_EANBLE
4426	nvram_set_aicloud_acc_list(aicloud_acc_list->ptr);
4427#else
4428	unlink("/tmp/aicloud_acc_list");
4429	FILE* fp = fopen("/tmp/aicloud_acc_list", "w");
4430	if(fp!=NULL){
4431		fprintf(fp, "%s", aicloud_acc_list->ptr);
4432		fclose(fp);
4433	}
4434#endif
4435
4436	buffer_free(aicloud_acc_list);
4437
4438}
4439
4440void free_aicloud_acc_info(aicloud_acc_info_t *aicloud_acc_info){
4441	buffer_free(aicloud_acc_info->username);
4442	buffer_free(aicloud_acc_info->password);
4443}
4444
4445void read_aicloud_acc_invite_list(){
4446
4447	char *nvram_aicloud_acc_invite_list = NULL;
4448
4449#if EMBEDDED_EANBLE
4450	nvram_aicloud_acc_invite_list = nvram_get_aicloud_acc_invite_list();
4451#else
4452	nvram_aicloud_acc_invite_list = read_whole_file("/tmp/aicloud_acc_invite_list");
4453#endif
4454
4455	if(nvram_aicloud_acc_invite_list==NULL){
4456		return;
4457	}
4458
4459	int len = strlen(nvram_aicloud_acc_invite_list);
4460	char* aicloud_acc_invite_list = malloc(len);
4461
4462	if(aicloud_acc_invite_list==NULL){
4463		return;
4464	}
4465
4466	memset(aicloud_acc_invite_list, '\0', len);
4467	strncpy(aicloud_acc_invite_list, nvram_aicloud_acc_invite_list, len);
4468
4469#if EMBEDDED_EANBLE
4470	#ifdef APP_IPKG
4471	if(nvram_aicloud_acc_invite_list!=NULL)
4472		free(nvram_aicloud_acc_invite_list);
4473	#endif
4474#else
4475	if(nvram_aicloud_acc_invite_list!=NULL)
4476		free(nvram_aicloud_acc_invite_list);
4477#endif
4478
4479	char * pch = strtok(aicloud_acc_invite_list, "<>");
4480	while(pch!=NULL){
4481
4482		aicloud_acc_invite_info_t *aicloud_acc_invite_info;
4483		aicloud_acc_invite_info = (aicloud_acc_invite_info_t *)calloc(1, sizeof(aicloud_acc_invite_info_t));
4484
4485		//- productid
4486		aicloud_acc_invite_info->productid = buffer_init();
4487		if(pch!=NULL && strcmp(pch, "none")!=0){
4488			buffer_copy_string_len(aicloud_acc_invite_info->productid, pch, strlen(pch));
4489			buffer_urldecode_path(aicloud_acc_invite_info->productid);
4490		}
4491
4492		//- deviceid
4493		pch = strtok(NULL,"<>");
4494		aicloud_acc_invite_info->deviceid = buffer_init();
4495		if(pch!=NULL && strcmp(pch, "none")!=0){
4496			buffer_copy_string_len(aicloud_acc_invite_info->deviceid, pch, strlen(pch));
4497			buffer_urldecode_path(aicloud_acc_invite_info->deviceid);
4498		}
4499
4500		//- token
4501		pch = strtok(NULL,"<>");
4502		aicloud_acc_invite_info->token = buffer_init();
4503		if(pch!=NULL && strcmp(pch, "none")!=0){
4504			buffer_copy_string_len(aicloud_acc_invite_info->token, pch, strlen(pch));
4505			buffer_urldecode_path(aicloud_acc_invite_info->token);
4506		}
4507
4508		//- permission
4509		pch = strtok(NULL,"<>");
4510		aicloud_acc_invite_info->permission = buffer_init();
4511		if(pch!=NULL && strcmp(pch, "none")!=0){
4512			buffer_copy_string_len(aicloud_acc_invite_info->permission, pch, strlen(pch));
4513			buffer_urldecode_path(aicloud_acc_invite_info->permission);
4514		}
4515
4516		//- bytes_in_avail
4517		pch = strtok(NULL,"<>");
4518		if(pch!=NULL)
4519			aicloud_acc_invite_info->bytes_in_avail = atoi(pch);
4520
4521		//- smart_access
4522		pch = strtok(NULL,"<>");
4523		if(pch!=NULL)
4524			aicloud_acc_invite_info->smart_access = atoi(pch);
4525
4526		//- security_code
4527		pch = strtok(NULL,"<>");
4528		aicloud_acc_invite_info->security_code = buffer_init();
4529		if(pch!=NULL && strcmp(pch, "none")!=0){
4530			buffer_copy_string_len(aicloud_acc_invite_info->security_code, pch, strlen(pch));
4531			buffer_urldecode_path(aicloud_acc_invite_info->security_code);
4532		}
4533
4534		//- status
4535		pch = strtok(NULL,"<>");
4536		if(pch!=NULL)
4537			aicloud_acc_invite_info->status = atoi(pch);
4538
4539		//- auth_type
4540		pch = strtok(NULL,"<>");
4541		if(pch!=NULL)
4542			aicloud_acc_invite_info->auth_type = atoi(pch);
4543
4544		//- createtime
4545		pch = strtok(NULL,"<>");
4546		if(pch!=NULL)
4547			aicloud_acc_invite_info->createtime = atoi(pch);
4548
4549		//- next
4550		pch = strtok(NULL,"<>");
4551
4552		DLIST_ADD(aicloud_acc_invite_info_list, aicloud_acc_invite_info);
4553	}
4554
4555	free(aicloud_acc_invite_list);
4556
4557}
4558
4559void append_text_to_list(buffer* buf, const char* text){
4560
4561	if(text==NULL || strcmp(text, "")==0){
4562		buffer_append_string(buf, "none");
4563		return;
4564	}
4565
4566	buffer_append_string_encoded(buf, text, strlen(text), ENCODING_REL_URI);
4567}
4568
4569void save_aicloud_acc_invite_list(){
4570	aicloud_acc_invite_info_t* c;
4571
4572	buffer* aicloud_acc_invite_list = buffer_init();
4573	buffer_copy_string(aicloud_acc_invite_list, "");
4574
4575	for (c = aicloud_acc_invite_info_list; c; c = c->next) {
4576
4577		if(!buffer_is_equal_string(aicloud_acc_invite_list, "", 0))
4578			buffer_append_string(aicloud_acc_invite_list, "<");
4579
4580		append_text_to_list(aicloud_acc_invite_list, c->productid->ptr);
4581
4582		buffer_append_string(aicloud_acc_invite_list, ">");
4583		append_text_to_list(aicloud_acc_invite_list, c->deviceid->ptr);
4584
4585		buffer_append_string(aicloud_acc_invite_list, ">");
4586		append_text_to_list(aicloud_acc_invite_list, c->token->ptr);
4587
4588		buffer_append_string(aicloud_acc_invite_list, ">");
4589		append_text_to_list(aicloud_acc_invite_list, c->permission->ptr);
4590
4591		char strByteInAvail[25] = {0};
4592		sprintf(strByteInAvail, "%lu", c->bytes_in_avail);
4593		buffer_append_string(aicloud_acc_invite_list, ">");
4594		append_text_to_list(aicloud_acc_invite_list, strByteInAvail);
4595
4596		char strSmartAccess[2] = {0};
4597		sprintf(strSmartAccess, "%d", c->smart_access);
4598		buffer_append_string(aicloud_acc_invite_list, ">");
4599		append_text_to_list(aicloud_acc_invite_list, strSmartAccess);
4600
4601		buffer_append_string(aicloud_acc_invite_list, ">");
4602		append_text_to_list(aicloud_acc_invite_list, c->security_code->ptr);
4603
4604		char strStatus[2] = {0};
4605		sprintf(strStatus, "%d", c->status);
4606		buffer_append_string(aicloud_acc_invite_list, ">");
4607		append_text_to_list(aicloud_acc_invite_list, strStatus);
4608
4609		char strAuthType[2] = {0};
4610		sprintf(strAuthType, "%d", c->auth_type);
4611		buffer_append_string(aicloud_acc_invite_list, ">");
4612		append_text_to_list(aicloud_acc_invite_list, strAuthType);
4613
4614		char strCreateTime[25] = {0};
4615		sprintf(strCreateTime, "%lu", c->createtime);
4616		buffer_append_string(aicloud_acc_invite_list, ">");
4617		append_text_to_list(aicloud_acc_invite_list, strCreateTime);
4618
4619	}
4620
4621#if EMBEDDED_EANBLE
4622	nvram_set_aicloud_acc_invite_list(aicloud_acc_invite_list->ptr);
4623#else
4624	unlink("/tmp/aicloud_acc_invite_list");
4625	FILE* fp = fopen("/tmp/aicloud_acc_invite_list", "w");
4626	if(fp!=NULL){
4627		fprintf(fp, "%s", aicloud_acc_invite_list->ptr);
4628		fclose(fp);
4629	}
4630#endif
4631
4632	buffer_free(aicloud_acc_invite_list);
4633}
4634
4635void free_aicloud_acc_invite_info(aicloud_acc_invite_info_t *aicloud_acc_invite_info){
4636	buffer_free(aicloud_acc_invite_info->productid);
4637	buffer_free(aicloud_acc_invite_info->deviceid);
4638	buffer_free(aicloud_acc_invite_info->token);
4639	buffer_free(aicloud_acc_invite_info->permission);
4640	buffer_free(aicloud_acc_invite_info->security_code);
4641}
4642#endif
4643