1
2#include "base.h"
3#include "log.h"
4#include "buffer.h"
5
6//#ifdef HAVE_LIBSMBCLIENT
7
8#include "response.h"
9
10#include "plugin.h"
11
12#include "stream.h"
13#include "stat_cache.h"
14
15#include "sys-mmap.h"
16
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <ctype.h>
20#include <stdlib.h>
21#include <string.h>
22#include <errno.h>
23#include <fcntl.h>
24#include <stdio.h>
25#include <assert.h>
26
27#include <unistd.h>
28#include <dirent.h>
29
30#include <sys/shm.h>
31#include <signal.h>
32#include <sys/vfs.h>
33
34#if EMBEDDED_EANBLE
35#ifndef APP_IPKG
36#include <utils.h>
37#include <shutils.h>
38#include <shared.h>
39#endif
40#include "nvram_control.h"
41
42#if 0
43#if HAVE_PUSHLOG
44#include <push_log.h>
45#endif
46#endif
47
48#endif
49
50#ifdef RTCONFIG_USB
51#include <disk_initial.h>
52#endif
53
54#include <curl/curl.h>
55#include <openssl/md5.h>
56#include <openssl/x509.h>
57
58int shmid;
59void* shared_memory = (void*)0;
60
61#ifdef SOURCEINSIGH
62	server *srv;
63	connection *con;
64	void *p_d;
65#endif
66
67#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H)
68#define USE_PROPPATCH
69#include <libxml/tree.h>
70#include <libxml/parser.h>
71
72#include <sqlite3.h>
73#endif
74
75#if 0
76#define HAVE_ICONV_H
77#include <iconv.h>
78#define MAX_ICONV_BUF 2048
79
80typedef enum {
81	ICONV_OK,
82	ICONV_TRYNEXT,
83	ICONV_FATAL
84} iconv_result;
85#endif
86/*
87#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_UUID_H)
88#define USE_LOCKS
89include <uuid/uuid.h>
90#endif
91*/
92
93#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H)
94#define USE_LOCKS
95#endif
96
97// smb client api header
98#include <unistd.h>
99
100#include <dirent.h>
101
102#include "libsmbclient.h"
103#include "mod_smbdav.h"
104
105#define DBG_ENABLE_MOD_SMBDAV 1
106#define DBE	DBG_ENABLE_MOD_SMBDAV
107
108//#define SCAN_MASTER_BROWSER
109time_t prv_ts = 0;
110
111#define HEADER(con, key)                                                \
112    (data_string *)array_get_element((con)->request.headers, (key))
113
114#if 0
115unsigned long prev_total_0 = 0;
116unsigned long prev_user_0 = 0;
117unsigned long prev_total_1 = 0;
118unsigned long prev_user_1 = 0;
119#else
120unsigned long prev_total[10];
121unsigned long prev_user[10];
122#endif
123
124#if 0
125
126extern handler_t ntlm_authentication_handler(server *srv, connection *con, plugin_data *p);
127extern handler_t basic_authentication_handler(server *srv, connection *con, plugin_data *p);
128
129static iconv_result
130do_iconv(const char* to_ces, const char* from_ces,
131	 char *inbuf,  size_t inbytesleft,
132	 char *outbuf_orig, size_t outbytesleft_orig)
133{
134#ifdef HAVE_ICONV_H
135	size_t rc;
136	iconv_result ret = ICONV_OK;
137
138	size_t outbytesleft = outbytesleft_orig - 1;
139	char* outbuf = outbuf_orig;
140
141	iconv_t cd  = iconv_open(to_ces, from_ces);
142
143	if(cd == (iconv_t)-1)
144	{
145		return ICONV_FATAL;
146	}
147	rc = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
148	//Cdbg(1, "outbuf=%s", outbuf);
149	if(rc == (size_t)-1)
150	{
151		Cdbg(1, "fail %s", strerror(errno));
152		if(errno == E2BIG)
153		{
154			ret = ICONV_FATAL;
155		}
156		else
157		{
158			ret = ICONV_TRYNEXT;
159			memset(outbuf_orig, '\0', outbytesleft_orig);
160		}
161	}
162	iconv_close(cd);
163
164	return ret;
165#else // HAVE_ICONV_H
166	return ICONV_FATAL;
167#endif // HAVE_ICONV_H
168}
169#endif
170
171size_t static curl_write_callback_func(void *ptr, size_t size, size_t count, void *stream)
172{
173   	/* ptr - your string variable.
174     	stream - data chuck you received */
175	char **response_ptr =  (char**)stream;
176
177    /* assuming the response is a string */
178    *response_ptr = strndup(ptr, (size_t)(size *count));
179
180  	//printf("%.*s", size, (char*)stream));
181   	//Cdbg(1, "callback_func.... %s", (char*)ptr);
182}
183
184static int is_host2(char *uri)
185{
186	char pWorkgroup[30]={0};
187	char pServer[64]={0};
188	char pShare[128]={0};
189	char pPath[128]={0};
190	smbc_parse_path(uri, pWorkgroup, pServer, pShare, pPath);
191
192	struct cli_state *cli;
193
194	if(pServer[0] == '\0')
195		return 0;
196
197	cli = smbc_cli_initialize();
198
199	uint32_t res = smbc_cli_connect(cli, pServer, SMB_PORT);
200	if(res) {
201		res = smbc_cli_connect(cli, pServer, NMB_PORT);
202	}
203Cdbg(DBE, "%s can %sbe connected..", uri, (res) ? "not " : "");
204	smbc_cli_shutdown(cli);
205
206	return !res;
207}
208
209static int is_host(char *host)
210{
211	struct cli_state *cli;
212	cli = smbc_cli_initialize();
213
214	uint32_t res = smbc_cli_connect(cli, host, SMB_PORT);
215
216	smbc_cli_shutdown(cli);
217
218	return !res;
219}
220
221/* simple combsort algorithm */
222void smbc_dirls_sort(smbc_dirls_entry_t **ent, int num) {
223	int gap = num;
224	int i, j;
225	int swapped;
226	smbc_dirls_entry_t *tmp;
227
228	do {
229		gap = (gap * 10) / 13;
230		if (gap == 9 || gap == 10)
231			gap = 11;
232		if (gap < 1)
233			gap = 1;
234		swapped = 0;
235
236		for (i = 0; i < num - gap; i++) {
237			j = i + gap;
238			if (strcmp(DIRLIST_ENT_NAME(ent[i]), DIRLIST_ENT_NAME(ent[j])) > 0) {
239				tmp = ent[i];
240				ent[i] = ent[j];
241				ent[j] = tmp;
242				swapped = 1;
243			}
244		}
245
246	} while (gap > 1 || swapped);
247}
248
249/* buffer must be able to hold "999.9K"
250 * conversion is simple but not perfect
251 */
252int smbc_list_directory_sizefmt(char *buf, off_t size)
253{
254	const char unit[] = "KMGTPE";	/* Kilo, Mega, Tera, Peta, Exa */
255	const char *u = unit - 1;		/* u will always increment at least once */
256	int remain;
257	char *out = buf;
258
259	if (size < 100)
260		size += 99;
261	if (size < 100)
262		size = 0;
263
264	while (1) {
265		remain = (int) size & 1023;
266		size >>= 10;
267		u++;
268		if ((size & (~0 ^ 1023)) == 0)
269			break;
270	}
271
272	remain /= 100;
273	if (remain > 9)
274		remain = 9;
275	if (size > 999) {
276		size   = 0;
277		remain = 9;
278		u++;
279	}
280
281	out += LI_ltostr(out, size);
282	out[0] = '.';
283	out[1] = remain + '0';
284	out[2] = *u;
285	out[3] = '\0';
286
287	return (out + 3 - buf);
288}
289
290static void get_auth_data_fn(const char * pServer,
291                 const char * pShare,
292                 char * pWorkgroup,
293                 int maxLenWorkgroup,
294                 char * pUsername,
295                 int maxLenUsername,
296                 char * pPassword,
297                 int maxLenPassword)
298{
299	UNUSED(pServer);
300	UNUSED(pShare);
301	UNUSED(maxLenWorkgroup);
302	UNUSED(maxLenUsername);
303	UNUSED(maxLenPassword);
304
305	UNUSED(pWorkgroup);
306	UNUSED(pUsername);
307	UNUSED(pPassword);
308}
309
310// XOR-based encryption
311static int handle_encrypt(buffer *buf, uint8_t *key, int keylen) {
312    int i;
313
314	for (i = 0; i < buf->used - 1; i++) {
315        buf->ptr[i] ^= (i > 0 ? buf->ptr[i - 1] : 0) ^ key[i % keylen];
316
317        // sanity check - result should be base64-encoded authinfo
318        if (! isprint(buf->ptr[i])) {
319            return -1;
320        }
321    }
322
323    return 0;
324}
325
326static int open_close_streaming_port(server* srv, int toOpen){
327	char cmd[BUFSIZ]="\0";
328	int rc = -1;
329
330#if EMBEDDED_EANBLE
331	char* webdav_http_port = nvram_get_webdav_http_port();
332#else
333	char* webdav_http_port = "8082";
334#endif
335
336	if(toOpen==1 && srv->is_streaming_port_opend == 0){
337		//- open streaming port
338
339		//- delete accept rule
340		sprintf(cmd, "iptables -D INPUT -p tcp -m tcp --dport %s -j ACCEPT", webdav_http_port);
341		rc = system(cmd);
342
343		//- delete drop rule
344		sprintf(cmd, "iptables -D INPUT -p tcp -m tcp --dport %s -j DROP", webdav_http_port);
345		rc = system(cmd);
346
347		//- add accept rule
348		sprintf(cmd, "iptables -I INPUT 1 -p tcp -m tcp --dport %s -j ACCEPT", webdav_http_port);
349		rc = system(cmd);
350	}
351	else if(toOpen==0 && srv->is_streaming_port_opend == 1){
352		//- close streaming port
353
354		//- check rule is existed?
355		//sprintf(cmd, "iptables -C INPUT -p tcp -m tcp --dport %s -j DROP", webdav_http_port);
356		//Cdbg(DBE, "%s", cmd);
357
358		//- delete accept rule
359		sprintf(cmd, "iptables -D INPUT -p tcp -m tcp --dport %s -j ACCEPT", webdav_http_port);
360		rc = system(cmd);
361
362		//- delete drop rule
363		sprintf(cmd, "iptables -D INPUT -p tcp -m tcp --dport %s -j DROP", webdav_http_port);
364		rc = system(cmd);
365
366		//- add drop rule
367		sprintf(cmd, "iptables -I INPUT 1 -p tcp -m tcp --dport %s -j DROP", webdav_http_port);
368		rc = system(cmd);
369	}
370
371	if(rc!=0){
372		return 0;
373	}
374
375	srv->last_no_ssl_connection_ts = srv->cur_ts;
376	srv->is_streaming_port_opend = toOpen;
377
378	return 1;
379}
380
381/* init the plugin data */
382INIT_FUNC(mod_smbdav_init) {
383
384	plugin_data *p;
385
386	p = calloc(1, sizeof(*p));
387
388	p->tmp_buf = buffer_init();
389
390	p->uri.scheme = buffer_init();
391	p->uri.path_raw = buffer_init();
392	p->uri.path = buffer_init();
393	p->uri.authority = buffer_init();
394
395	p->physical.path = buffer_init();
396	p->physical.rel_path = buffer_init();
397	p->physical.doc_root = buffer_init();
398	p->physical.basedir = buffer_init();
399
400	int          dbglv = 0;
401	smbc_init(get_auth_data_fn, dbglv);
402
403	//stop_arpping_process();
404
405	memset(prev_total, 0, sizeof(prev_total));
406	memset(prev_user, 0, sizeof(prev_user));
407
408	Cdbg(DBE,"complete smbc_init...");
409
410	return p;
411}
412
413URIHANDLER_FUNC(mod_msbdav_connection_close) {
414	UNUSED(srv);
415
416	if(con->smb_info && con->smb_info->cli != NULL) {
417		smbc_cli_shutdown(con->smb_info->cli);
418	}
419
420	return HANDLER_GO_ON;
421}
422
423/* detroy the plugin data */
424FREE_FUNC(mod_smbdav_free) {
425	plugin_data *p = p_d;
426
427	UNUSED(srv);
428
429	if (!p) return HANDLER_GO_ON;
430
431	if (p->config_storage) {
432		size_t i;
433		for (i = 0; i < srv->config_context->used; i++) {
434			plugin_config *s = p->config_storage[i];
435
436			if (!s) continue;
437
438			buffer_free(s->sqlite_db_name);
439#ifdef USE_PROPPATCH
440			if (s->sql) {
441				sqlite3_finalize(s->stmt_delete_prop);
442				sqlite3_finalize(s->stmt_delete_uri);
443				sqlite3_finalize(s->stmt_copy_uri);
444				sqlite3_finalize(s->stmt_move_uri);
445				sqlite3_finalize(s->stmt_update_prop);
446				sqlite3_finalize(s->stmt_select_prop);
447				sqlite3_finalize(s->stmt_select_propnames);
448
449				sqlite3_finalize(s->stmt_read_lock);
450				sqlite3_finalize(s->stmt_read_lock_by_uri);
451				sqlite3_finalize(s->stmt_create_lock);
452				sqlite3_finalize(s->stmt_remove_lock);
453				sqlite3_finalize(s->stmt_refresh_lock);
454				sqlite3_close(s->sql);
455			}
456#endif
457
458			//- 20130304 JerryLin add
459			buffer_free(s->sqlite_minidlna_db_name);
460			if (s->sql_minidlna) {
461				sqlite3_close(s->sql_minidlna);
462			}
463
464			free(s);
465		}
466		free(p->config_storage);
467	}
468
469	buffer_free(p->uri.scheme);
470	buffer_free(p->uri.path_raw);
471	buffer_free(p->uri.path);
472	buffer_free(p->uri.authority);
473
474	buffer_free(p->physical.path);
475	buffer_free(p->physical.rel_path);
476	buffer_free(p->physical.doc_root);
477	buffer_free(p->physical.basedir);
478
479	buffer_free(p->tmp_buf);
480
481	free(p);
482
483	stop_arpping_process();
484
485	//- close streaming port
486	open_close_streaming_port(srv, 0);
487
488	return HANDLER_GO_ON;
489}
490
491/* handle plugin config and check values */
492
493SETDEFAULTS_FUNC(mod_smbdav_set_defaults) {
494	Cdbg(1, "mod_smbdav_set_defaults");
495	plugin_data *p = p_d;
496	size_t i = 0;
497
498	config_values_t cv[] = {
499		{ "smbdav.activate",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
500		{ "smbdav.is-readonly",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
501		{ "smbdav.sqlite-db-name",      NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION },       /* 2 */
502		{ "smbdav.log-xml",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
503		{ "smbdav.sqlite-minidlna-db-name", NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION },   /* 4 */
504		{ NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
505	};
506
507	if (!p) return HANDLER_ERROR;
508
509	p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
510
511	for (i = 0; i < srv->config_context->used; i++) {
512		plugin_config *s;
513
514		s = calloc(1, sizeof(plugin_config));
515		s->sqlite_db_name = buffer_init();
516
517		//- 20130304 JerryLin add
518		s->sqlite_minidlna_db_name = buffer_init();
519
520		cv[0].destination = &(s->enabled);
521		cv[1].destination = &(s->is_readonly);
522		cv[2].destination = s->sqlite_db_name;
523		cv[3].destination = &(s->log_xml);
524		cv[4].destination = s->sqlite_minidlna_db_name;
525
526		p->config_storage[i] = s;
527
528		if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
529			return HANDLER_ERROR;
530		}
531
532#ifdef USE_MINIDLNA_DB
533		//- 20130304 JerryLin add
534		if (!buffer_is_empty(s->sqlite_minidlna_db_name)) {
535			if (SQLITE_OK != sqlite3_open(s->sqlite_minidlna_db_name->ptr, &(s->sql_minidlna))) {
536				log_error_write(srv, __FILE__, __LINE__, "sbs", "sqlite3_open failed for",
537						s->sqlite_minidlna_db_name,
538						sqlite3_errmsg(s->sql_minidlna));
539				Cdbg(DBE, "Fail to open minidlna db %s", s->sqlite_minidlna_db_name->ptr);
540			}
541		}
542#endif
543
544		if (!buffer_is_empty(s->sqlite_db_name)) {
545#ifdef USE_PROPPATCH
546			const char *next_stmt;
547			char *err;
548
549			if (SQLITE_OK != sqlite3_open(s->sqlite_db_name->ptr, &(s->sql))) {
550				log_error_write(srv, __FILE__, __LINE__, "sbs", "sqlite3_open failed for",
551						s->sqlite_db_name,
552						sqlite3_errmsg(s->sql));
553				return HANDLER_ERROR;
554			}
555
556			if (SQLITE_OK != sqlite3_exec(s->sql,
557					"CREATE TABLE properties ("
558					"  resource TEXT NOT NULL,"
559					"  prop TEXT NOT NULL,"
560					"  ns TEXT NOT NULL,"
561					"  value TEXT NOT NULL,"
562					"  PRIMARY KEY(resource, prop, ns))",
563					NULL, NULL, &err)) {
564
565				if (0 != strcmp(err, "table properties already exists")) {
566					log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
567					sqlite3_free(err);
568
569					return HANDLER_ERROR;
570				}
571				sqlite3_free(err);
572			}
573
574			if (SQLITE_OK != sqlite3_prepare(s->sql,
575				CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
576				&(s->stmt_select_prop), &next_stmt)) {
577				/* prepare failed */
578
579				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
580				return HANDLER_ERROR;
581			}
582
583			if (SQLITE_OK != sqlite3_prepare(s->sql,
584				CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"),
585				&(s->stmt_select_propnames), &next_stmt)) {
586				/* prepare failed */
587
588				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
589				return HANDLER_ERROR;
590			}
591
592
593			if (SQLITE_OK != sqlite3_prepare(s->sql,
594				CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"),
595				&(s->stmt_update_prop), &next_stmt)) {
596				/* prepare failed */
597
598				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
599				return HANDLER_ERROR;
600			}
601
602			if (SQLITE_OK != sqlite3_prepare(s->sql,
603				CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
604				&(s->stmt_delete_prop), &next_stmt)) {
605				/* prepare failed */
606				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
607
608				return HANDLER_ERROR;
609			}
610
611			if (SQLITE_OK != sqlite3_prepare(s->sql,
612				CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"),
613				&(s->stmt_delete_uri), &next_stmt)) {
614				/* prepare failed */
615				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
616
617				return HANDLER_ERROR;
618			}
619
620			if (SQLITE_OK != sqlite3_prepare(s->sql,
621				CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"),
622				&(s->stmt_copy_uri), &next_stmt)) {
623				/* prepare failed */
624				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
625
626				return HANDLER_ERROR;
627			}
628
629			if (SQLITE_OK != sqlite3_prepare(s->sql,
630				CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"),
631				&(s->stmt_move_uri), &next_stmt)) {
632				/* prepare failed */
633				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
634
635				return HANDLER_ERROR;
636			}
637
638			/* LOCKS */
639
640			if (SQLITE_OK != sqlite3_exec(s->sql,
641					"CREATE TABLE locks ("
642					"  locktoken TEXT NOT NULL,"
643					"  resource TEXT NOT NULL,"
644					"  lockscope TEXT NOT NULL,"
645					"  locktype TEXT NOT NULL,"
646					"  owner TEXT NOT NULL,"
647					"  depth INT NOT NULL,"
648					"  timeout TIMESTAMP NOT NULL,"
649					"  PRIMARY KEY(locktoken))",
650					NULL, NULL, &err)) {
651
652				if (0 != strcmp(err, "table locks already exists")) {
653					log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
654					sqlite3_free(err);
655
656					return HANDLER_ERROR;
657				}
658				sqlite3_free(err);
659			}
660
661			if (SQLITE_OK != sqlite3_prepare(s->sql,
662				CONST_STR_LEN("INSERT INTO locks (locktoken, resource, lockscope, locktype, owner, depth, timeout) VALUES (?,?,?,?,?,?, CURRENT_TIME + 600)"),
663				&(s->stmt_create_lock), &next_stmt)) {
664				/* prepare failed */
665				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
666
667				return HANDLER_ERROR;
668			}
669
670			if (SQLITE_OK != sqlite3_prepare(s->sql,
671				CONST_STR_LEN("DELETE FROM locks WHERE locktoken = ?"),
672				&(s->stmt_remove_lock), &next_stmt)) {
673				/* prepare failed */
674				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
675
676				return HANDLER_ERROR;
677			}
678
679			if (SQLITE_OK != sqlite3_prepare(s->sql,
680				CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE locktoken = ?"),
681				&(s->stmt_read_lock), &next_stmt)) {
682				/* prepare failed */
683				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
684
685				return HANDLER_ERROR;
686			}
687
688			if (SQLITE_OK != sqlite3_prepare(s->sql,
689				CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE resource = ?"),
690				&(s->stmt_read_lock_by_uri), &next_stmt)) {
691				/* prepare failed */
692				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
693
694				return HANDLER_ERROR;
695			}
696
697			if (SQLITE_OK != sqlite3_prepare(s->sql,
698				CONST_STR_LEN("UPDATE locks SET timeout = CURRENT_TIME + 600 WHERE locktoken = ?"),
699				&(s->stmt_refresh_lock), &next_stmt)) {
700				/* prepare failed */
701				log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
702
703				return HANDLER_ERROR;
704			}
705
706
707#else
708			log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-smbdav-props");
709			return HANDLER_ERROR;
710#endif
711		}
712	}
713
714	return HANDLER_GO_ON;
715}
716
717#define PATCH_OPTION(x) \
718	p->conf.x = s->x;
719static int mod_smbdav_patch_connection(server *srv, connection *con, plugin_data *p) {
720	size_t i, j;
721	plugin_config *s = p->config_storage[0];
722
723	PATCH_OPTION(enabled);
724	PATCH_OPTION(is_readonly);
725	PATCH_OPTION(log_xml);
726	//PATCH_OPTION(always_auth);
727
728#ifdef USE_PROPPATCH
729	PATCH_OPTION(sql);
730	PATCH_OPTION(stmt_update_prop);
731	PATCH_OPTION(stmt_delete_prop);
732	PATCH_OPTION(stmt_select_prop);
733	PATCH_OPTION(stmt_select_propnames);
734
735	PATCH_OPTION(stmt_delete_uri);
736	PATCH_OPTION(stmt_move_uri);
737	PATCH_OPTION(stmt_copy_uri);
738
739	PATCH_OPTION(stmt_remove_lock);
740	PATCH_OPTION(stmt_refresh_lock);
741	PATCH_OPTION(stmt_create_lock);
742	PATCH_OPTION(stmt_read_lock);
743	PATCH_OPTION(stmt_read_lock_by_uri);
744#endif
745
746#ifdef USE_MINIDLNA_DB
747	PATCH_OPTION(sqlite_minidlna_db_name);
748	PATCH_OPTION(sql_minidlna);
749#endif
750
751	/* skip the first, the global context */
752	for (i = 1; i < srv->config_context->used; i++) {
753		data_config *dc = (data_config *)srv->config_context->data[i];
754		s = p->config_storage[i];
755
756		/* condition didn't match */
757		if (!config_check_cond(srv, con, dc)) continue;
758
759		/* merge config */
760		for (j = 0; j < dc->value->used; j++) {
761			data_unset *du = dc->value->data[j];
762
763			if (buffer_is_equal_string(du->key, CONST_STR_LEN("smbdav.activate"))) {
764				PATCH_OPTION(enabled);
765			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("smbdav.is-readonly"))) {
766				PATCH_OPTION(is_readonly);
767			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("smbdav.log-xml"))) {
768				PATCH_OPTION(log_xml);
769			//} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("smbdav.always-auth"))) {
770			//	PATCH_OPTION(always_auth);
771			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("smbdav.sqlite-db-name"))) {
772#ifdef USE_PROPPATCH
773				PATCH_OPTION(sql);
774				PATCH_OPTION(stmt_update_prop);
775				PATCH_OPTION(stmt_delete_prop);
776				PATCH_OPTION(stmt_select_prop);
777				PATCH_OPTION(stmt_select_propnames);
778
779				PATCH_OPTION(stmt_delete_uri);
780				PATCH_OPTION(stmt_move_uri);
781				PATCH_OPTION(stmt_copy_uri);
782
783				PATCH_OPTION(stmt_remove_lock);
784				PATCH_OPTION(stmt_refresh_lock);
785				PATCH_OPTION(stmt_create_lock);
786				PATCH_OPTION(stmt_read_lock);
787				PATCH_OPTION(stmt_read_lock_by_uri);
788#endif
789			}
790			else if (buffer_is_equal_string(du->key, CONST_STR_LEN("smbdav.sqlite-minidlna-db-name"))) {
791#ifdef USE_MINIDLNA_DB
792				PATCH_OPTION(sqlite_minidlna_db_name);
793				PATCH_OPTION(sql_minidlna);
794#endif
795			}
796		}
797	}
798
799	return 0;
800}
801
802URIHANDLER_FUNC(mod_smbdav_uri_handler) {
803	plugin_data *p = p_d;
804
805	if (con->uri.path->used == 0)
806		return HANDLER_GO_ON;
807
808	mod_smbdav_patch_connection(srv, con, p);
809
810	if (!p->conf.enabled)
811		return HANDLER_GO_ON;
812
813	char pWorkgroup[30]={0};
814	char pServer[64]={0};
815	char pShare[128]={0};
816	char pPath[128]={0};
817	smbc_parse_path(con->physical.path->ptr, pWorkgroup, pServer, pShare, pPath);
818
819	switch (con->request.http_method) {
820	case HTTP_METHOD_OPTIONS:
821		/* we fake a little bit but it makes MS W2k happy and it let's us mount the volume */
822		response_header_overwrite(srv, con, CONST_STR_LEN("DAV"), CONST_STR_LEN("1,2"));
823		response_header_overwrite(srv, con, CONST_STR_LEN("MS-Author-Via"), CONST_STR_LEN("DAV"));
824
825		if (p->conf.is_readonly) {
826			response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND"));
827		} else {
828			response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK"));
829		}
830		break;
831	default:
832		break;
833	}
834
835	/* not found */
836
837
838	return HANDLER_GO_ON;
839}
840
841static int is_usbdisk_exist(server *srv, connection *con, const char* usbdisk_name){
842
843	Cdbg(1, "is_usbdisk_exist");
844	#if EMBEDDED_EANBLE
845	char *a = nvram_get_webdavaidisk();
846	if(strcmp( a, "0" ) == 0)
847		return 0;
848	#ifdef APP_IPKG
849	free(a);
850	#endif
851	#endif
852
853	config_values_t cv[] = {
854		{ "alias.url",					NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },		 /* 0 */
855		{ NULL, 						NULL, T_CONFIG_UNSET,  T_CONFIG_SCOPE_UNSET }
856	};
857
858	int found_file = 0;
859	size_t i, k;
860	for (i = 1; i < srv->config_context->used; i++) {
861
862		array* alias = array_init();
863		cv[0].destination = alias;
864
865		if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
866			continue;
867		}
868
869		for (k = 0; k < alias->used; k++) {
870			data_string *ds = (data_string *)alias->data[k];
871			Cdbg(1, "ds=%s, usbdisk_name=%s", ds->key->ptr, usbdisk_name);
872			if( strstr(ds->key->ptr, usbdisk_name) ){
873				Cdbg(1, "ds->value=%s, usbdisk_name=%s", ds->value->ptr, usbdisk_name);
874				DIR *dir;
875				if (NULL != (dir = opendir(ds->value->ptr))) {
876					struct dirent *de;
877					while(NULL != (de = readdir(dir))) {
878
879						if(strcmp(de->d_name, ".")==0||strcmp(de->d_name, "..")==0)
880							continue;
881
882						found_file = 1;
883						//Cdbg(DBE, "alias->data[k]->key=%s, value=%s, de->d_name=%s", ds->key->ptr, ds->value->ptr, de->d_name );
884						break;
885					}
886					closedir(dir);
887				}
888
889				break;
890			}
891
892		}
893
894		array_free(alias);
895
896		if(found_file==1)
897			break;
898
899	}
900
901	return found_file;
902}
903
904static int smbdav_gen_prop_tag(server *srv, connection *con,
905		char *prop_name,
906		char *prop_ns,
907		char *value,
908		buffer *b) {
909
910	UNUSED(srv);
911	UNUSED(con);
912
913	if (value) {
914		buffer_append_string_len(b,CONST_STR_LEN("<"));
915		buffer_append_string(b, prop_name);
916		buffer_append_string_len(b, CONST_STR_LEN(" xmlns=\""));
917		buffer_append_string(b, prop_ns);
918		buffer_append_string_len(b, CONST_STR_LEN("\">"));
919
920		buffer_append_string(b, value);
921
922		buffer_append_string_len(b,CONST_STR_LEN("</"));
923		buffer_append_string(b, prop_name);
924		buffer_append_string_len(b, CONST_STR_LEN(">"));
925	} else {
926		buffer_append_string_len(b,CONST_STR_LEN("<"));
927		buffer_append_string(b, prop_name);
928		buffer_append_string_len(b, CONST_STR_LEN(" xmlns=\""));
929		buffer_append_string(b, prop_ns);
930		buffer_append_string_len(b, CONST_STR_LEN("\"/>"));
931	}
932
933	return 0;
934}
935
936
937static int smbdav_gen_response_status_tag(server *srv, connection *con, physical *dst, int status, buffer *b) {
938	UNUSED(srv);
939
940	buffer_append_string_len(b,CONST_STR_LEN("<D:response xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"));
941
942	buffer_append_string_len(b,CONST_STR_LEN("<D:href>\n"));
943	buffer_append_string_buffer(b, dst->rel_path);
944	buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
945	buffer_append_string_len(b,CONST_STR_LEN("<D:status>\n"));
946
947	if (con->request.http_version == HTTP_VERSION_1_1) {
948		buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 "));
949	} else {
950		buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
951	}
952	buffer_append_int(b, status);
953	buffer_append_string_len(b, CONST_STR_LEN(" "));
954	buffer_append_string(b, get_http_status_name(status));
955
956	buffer_append_string_len(b,CONST_STR_LEN("</D:status>\n"));
957	buffer_append_string_len(b,CONST_STR_LEN("</D:response>\n"));
958
959	return 0;
960}
961
962static int smbdav_delete_file(server *srv, connection *con, plugin_data *p, physical *dst, buffer *b)
963{
964	int status = 0;
965
966	/* try to unlink it */
967	if (-1 == smbc_wrapper_unlink(con, dst->path->ptr)) {
968		switch(errno) {
969		case EACCES:
970		case EPERM:
971			/* 403 */
972			status = 403;
973			break;
974		default:
975			status = 501;
976			break;
977		}
978		smbdav_gen_response_status_tag(srv, con, dst, status, b);
979	} else {
980#ifdef USE_PROPPATCH
981		sqlite3_stmt *stmt = p->conf.stmt_delete_uri;
982
983		if (!stmt) {
984			status = 403;
985			smbdav_gen_response_status_tag(srv, con, dst, status, b);
986		} else {
987			sqlite3_reset(stmt);
988
989			/* bind the values to the insert */
990
991			sqlite3_bind_text(stmt, 1,
992					  dst->rel_path->ptr,
993					  dst->rel_path->used - 1,
994					  SQLITE_TRANSIENT);
995
996			if (SQLITE_DONE != sqlite3_step(stmt)) {
997				/* */
998			}
999		}
1000#else
1001		UNUSED(p);
1002#endif
1003	}
1004
1005	return (status != 0);
1006}
1007
1008static int smbdav_delete_dir(server *srv, connection *con, plugin_data *p, physical *dst, buffer *b)
1009{
1010	DIR *dir;
1011	int have_multi_status = 0;
1012	physical d;
1013
1014	d.path = buffer_init();
1015	d.rel_path = buffer_init();
1016
1017	if (NULL != (dir = smbc_wrapper_opendir(con, dst->path->ptr))) {
1018		struct smbc_dirent *de;
1019
1020		while(NULL != (de = smbc_wrapper_readdir(con, dir))) {
1021			struct stat st;
1022			int status = 0;
1023
1024			if ((de->name[0] == '.' && de->name[1] == '\0')  ||
1025			    (de->name[0] == '.' && de->name[1] == '.' && de->name[2] == '\0')) {
1026				continue;
1027				/* ignore the parent dir */
1028			}
1029
1030			buffer_copy_buffer(d.path, dst->path);
1031			buffer_append_slash(d.path);
1032			buffer_append_string(d.path, de->name);
1033
1034			buffer_copy_buffer(d.rel_path, dst->rel_path);
1035			buffer_append_slash(d.rel_path);
1036			buffer_append_string(d.rel_path, de->name);
1037
1038			/* stat and unlink afterwards */
1039			if (-1 == smbc_wrapper_stat(con, d.path->ptr, &st)) {
1040				/* don't about it yet, rmdir will fail too */
1041			} else if (S_ISDIR(st.st_mode)) {
1042				have_multi_status = smbdav_delete_dir(srv, con, p, &d, b);
1043
1044				/* try to unlink it */
1045				if (-1 == smbc_wrapper_rmdir(con, d.path->ptr)) {
1046					switch(errno) {
1047					case EACCES:
1048					case EPERM:
1049						/* 403 */
1050						status = 403;
1051						break;
1052					default:
1053						status = 501;
1054						break;
1055					}
1056					have_multi_status = 1;
1057
1058					smbdav_gen_response_status_tag(srv, con, &d, status, b);
1059				} else {
1060#ifdef USE_PROPPATCH
1061					sqlite3_stmt *stmt = p->conf.stmt_delete_uri;
1062
1063					status = 0;
1064
1065					if (stmt) {
1066						sqlite3_reset(stmt);
1067
1068						/* bind the values to the insert */
1069
1070						sqlite3_bind_text(stmt, 1,
1071								  d.rel_path->ptr,
1072								  d.rel_path->used - 1,
1073								  SQLITE_TRANSIENT);
1074
1075						if (SQLITE_DONE != sqlite3_step(stmt)) {
1076							/* */
1077						}
1078					}
1079#endif
1080				}
1081			} else {
1082				have_multi_status = smbdav_delete_file(srv, con, p, &d, b);
1083			}
1084		}
1085		smbc_wrapper_closedir(con, dir);
1086
1087		buffer_free(d.path);
1088		buffer_free(d.rel_path);
1089	}
1090
1091	return have_multi_status;
1092}
1093
1094static int smbdav_copy_file(server *srv, connection *con, plugin_data *p, physical *src, physical *dst, int overwrite)
1095{
1096	int status = 0, ret, src_fd = -1, dst_fd = -1;
1097	char buff[2048];
1098
1099	UNUSED(srv);
1100	UNUSED(con);
1101
1102#if EMBEDDED_EANBLE
1103	char *a = nvram_get_productid();
1104	char usbdisk_path[100]="\0";
1105	strcpy(usbdisk_path, "/");
1106	strcat(usbdisk_path, a);
1107	#ifdef APP_IPKG
1108	free(a);
1109	#endif
1110#else
1111	char usbdisk_path[10]="/usbdisk";
1112#endif
1113
1114	//int index = strstr(dst->path->ptr, usbdisk_path) - dst->path->ptr;
1115	//if(index==0){
1116	if(prefix_is(dst->path->ptr, usbdisk_path)==1){
1117		if (-1 == (dst_fd = fopen(dst->rel_path->ptr, "wb"))) {
1118			/* opening the destination failed for some reason */
1119			switch(errno) {
1120				case EEXIST:
1121					status = 412;
1122					break;
1123				case EISDIR:
1124					status = 409;
1125					break;
1126				case ENOENT:
1127					/* at least one part in the middle wasn't existing */
1128					status = 409;
1129					break;
1130				default:
1131					status = 403;
1132					break;
1133			}
1134			fclose(dst_fd);
1135			return status;
1136		}
1137
1138		if (src_fd = smbc_open(src->path->ptr, O_RDONLY, WEBDAV_FILE_MODE)) {
1139			do {
1140				ret = smbc_read(src_fd, buff, sizeof(buff));
1141				if (ret > 0) {
1142					if (-1 == fwrite(buff, sizeof(char), sizeof(buff), dst_fd)) {
1143						switch(errno) {
1144						case ENOSPC:
1145							status = 507;
1146							break;
1147						default:
1148							status = 403;
1149							break;
1150						}
1151
1152						smbc_close(src_fd);
1153						fclose(dst_fd);
1154						return status;
1155					}
1156				}
1157			} while (ret > 0);
1158		}
1159
1160		smbc_close(src_fd);
1161		fclose(dst_fd);
1162	}
1163	else{
1164		if (-1 == (dst_fd = smbc_open(dst->path->ptr, O_WRONLY|O_TRUNC|O_CREAT|(overwrite ? 0 : O_EXCL), WEBDAV_FILE_MODE))) {
1165			/* opening the destination failed for some reason */
1166			switch(errno) {
1167			case EEXIST:
1168				status = 412;
1169				break;
1170			case EISDIR:
1171				status = 409;
1172				break;
1173			case ENOENT:
1174				/* at least one part in the middle wasn't existing */
1175				status = 409;
1176				break;
1177			default:
1178				status = 403;
1179				break;
1180			}
1181			smbc_close(dst_fd);
1182			return status;
1183		}
1184
1185		if (src_fd = smbc_open(src->path->ptr, O_RDONLY, WEBDAV_FILE_MODE)) {
1186			do {
1187				ret = smbc_read(src_fd, buff, sizeof(buff));
1188				if (ret > 0) {
1189					if (-1 == smbc_write(dst_fd, buff, ret)) {
1190						switch(errno) {
1191						case ENOSPC:
1192							status = 507;
1193							break;
1194						default:
1195							status = 403;
1196							break;
1197						}
1198
1199						smbc_close(src_fd);
1200						smbc_close(dst_fd);
1201						return status;
1202					}
1203				}
1204			} while (ret > 0);
1205		}
1206
1207		smbc_close(src_fd);
1208		smbc_close(dst_fd);
1209	}
1210
1211#ifdef USE_PROPPATCH
1212	if (0 == status) {
1213		/* copy worked fine, copy connected properties */
1214		sqlite3_stmt *stmt = p->conf.stmt_copy_uri;
1215
1216		if (stmt) {
1217			sqlite3_reset(stmt);
1218
1219			/* bind the values to the insert */
1220			sqlite3_bind_text(stmt, 1,
1221					  dst->rel_path->ptr,
1222					  dst->rel_path->used - 1,
1223					  SQLITE_TRANSIENT);
1224
1225			sqlite3_bind_text(stmt, 2,
1226					  src->rel_path->ptr,
1227					  src->rel_path->used - 1,
1228					  SQLITE_TRANSIENT);
1229
1230			if (SQLITE_DONE != sqlite3_step(stmt)) {
1231				/* */
1232			}
1233		}
1234	}
1235#else
1236	UNUSED(p);
1237#endif
1238
1239	return status;
1240}
1241
1242static int smbdav_create_dir(server *srv, connection *con, physical *src){
1243	int result=-1;
1244
1245#if EMBEDDED_EANBLE
1246	char *a = nvram_get_productid();
1247	char usbdisk_path[100]="\0";
1248	strcpy(usbdisk_path, "/");
1249	strcat(usbdisk_path, a);
1250	#ifdef APP_IPKG
1251	free(a);
1252	#endif
1253#else
1254	char usbdisk_path[10]="/usbdisk";
1255#endif
1256
1257	//int index = strstr(src->path->ptr, usbdisk_path) - src->path->ptr;
1258	//if(index==0){
1259	if(prefix_is(src->path->ptr, usbdisk_path)==1){
1260		struct stat st;
1261
1262		if (-1 == stat(src->rel_path->ptr, &st)) {
1263			result = mkdir(src->rel_path->ptr, WEBDAV_DIR_MODE);
1264		}
1265		else if (S_ISDIR(st.st_mode)) {
1266			result = 0;
1267		}
1268	}
1269	else{
1270		result = smbc_wrapper_mkdir(con, src->path->ptr, WEBDAV_DIR_MODE);
1271	}
1272
1273	return result;
1274}
1275
1276static int smbdav_copy_dir(server *srv, connection *con, plugin_data *p, physical *src, physical *dst, int overwrite)
1277{
1278	DIR *srcdir;
1279	int status = 0;
1280
1281	if (NULL != (srcdir = smbc_wrapper_opendir(con, src->path->ptr))) {
1282		struct smbc_dirent *de;
1283		physical s, d;
1284
1285		s.path = buffer_init();
1286		s.rel_path = buffer_init();
1287
1288		d.path = buffer_init();
1289		d.rel_path = buffer_init();
1290
1291		while (NULL != (de = smbc_wrapper_readdir(con, srcdir))) {
1292			struct stat st;
1293
1294			if( (de->name[0] == '.' && de->name[1] == '\0') ||
1295		        (de->name[0] == '.' && de->name[1] == '.' && de->name[2] == '\0')) {
1296				continue;
1297			}
1298
1299			buffer_copy_buffer(s.path, src->path);
1300			buffer_append_slash(s.path);
1301			buffer_append_string(s.path, de->name);
1302
1303			buffer_copy_buffer(d.path, dst->path);
1304			buffer_append_slash(d.path);
1305			buffer_append_string(d.path, de->name);
1306
1307			buffer_copy_buffer(s.rel_path, src->rel_path);
1308			buffer_append_slash(s.rel_path);
1309			buffer_append_string(s.rel_path, de->name);
1310
1311			buffer_copy_buffer(d.rel_path, dst->rel_path);
1312			buffer_append_slash(d.rel_path);
1313			buffer_append_string(d.rel_path, de->name);
1314
1315			if (-1 == smbc_wrapper_stat(con, s.path->ptr, &st)) {
1316				/* why ? */
1317			} else if (S_ISDIR(st.st_mode)) {
1318				/* a directory */
1319				if (-1 == smbdav_create_dir(srv, con, &d) && errno != EEXIST) {
1320					/* WTH ? */
1321				} else {
1322#ifdef USE_PROPPATCH
1323					sqlite3_stmt *stmt = p->conf.stmt_copy_uri;
1324
1325					if (0 != (status = smbdav_copy_dir(srv, con, p, &s, &d, overwrite))) {
1326						break;
1327					}
1328
1329					/* directory is copied, copy the properties too */
1330					if (stmt) {
1331						sqlite3_reset(stmt);
1332
1333						/* bind the values to the insert */
1334						sqlite3_bind_text(stmt, 1,
1335							  dst->rel_path->ptr,
1336							  dst->rel_path->used - 1,
1337							  SQLITE_TRANSIENT);
1338
1339						sqlite3_bind_text(stmt, 2,
1340							  src->rel_path->ptr,
1341							  src->rel_path->used - 1,
1342							  SQLITE_TRANSIENT);
1343
1344						if (SQLITE_DONE != sqlite3_step(stmt)) {
1345							/* */
1346						}
1347					}
1348#endif
1349				}
1350			}
1351			else if (S_ISREG(st.st_mode)) {
1352				/* a plain file */
1353				if (0 != (status = smbdav_copy_file(srv, con, p, &s, &d, overwrite))) {
1354					break;
1355				}
1356			}
1357		}
1358
1359		buffer_free(s.path);
1360		buffer_free(s.rel_path);
1361		buffer_free(d.path);
1362		buffer_free(d.rel_path);
1363
1364		smbc_wrapper_closedir(con, srcdir);
1365	}
1366
1367	return status;
1368}
1369
1370static int smbdav_get_live_property(server *srv, connection *con, plugin_data *p, physical *dst, char *prop_name, buffer *b) {
1371	stat_cache_entry *sce = NULL;
1372	int found = 0;
1373
1374	UNUSED(p);
1375
1376	if (HANDLER_ERROR != (stat_cache_get_entry(srv, con, dst->path, &sce))) {
1377		char ctime_buf[] = "2005-08-18T07:27:16Z";
1378		char mtime_buf[] = "Thu, 18 Aug 2005 07:27:16 GMT";
1379		size_t k;
1380
1381		if (0 == strcmp(prop_name, "resourcetype")) {
1382			if (S_ISDIR(sce->st.st_mode)) {
1383				buffer_append_string_len(b, CONST_STR_LEN("<D:resourcetype><D:collection/></D:resourcetype>"));
1384				found = 1;
1385			}
1386		} else if (0 == strcmp(prop_name, "getcontenttype")) {
1387			if (S_ISDIR(sce->st.st_mode)) {
1388				buffer_append_string_len(b, CONST_STR_LEN("<D:getcontenttype>httpd/unix-directory</D:getcontenttype>"));
1389				found = 1;
1390			} else if(S_ISREG(sce->st.st_mode)) {
1391				for (k = 0; k < con->conf.mimetypes->used; k++) {
1392					data_string *ds = (data_string *)con->conf.mimetypes->data[k];
1393
1394					if (ds->key->used == 0) continue;
1395
1396					if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) {
1397						buffer_append_string_len(b,CONST_STR_LEN("<D:getcontenttype>"));
1398						buffer_append_string_buffer(b, ds->value);
1399						buffer_append_string_len(b, CONST_STR_LEN("</D:getcontenttype>"));
1400						found = 1;
1401
1402						break;
1403					}
1404				}
1405			}
1406		} else if (0 == strcmp(prop_name, "creationdate")) {
1407			//buffer_append_string_len(b, CONST_STR_LEN("<D:creationdate ns0:dt=\"dateTime.tz\">"));
1408			buffer_append_string_len(b, CONST_STR_LEN("<D:creationdate>"));
1409			strftime(ctime_buf, sizeof(ctime_buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&(sce->st.st_ctime)));
1410			buffer_append_string(b, ctime_buf);
1411			buffer_append_string_len(b, CONST_STR_LEN("</D:creationdate>"));
1412			found = 1;
1413		} else if (0 == strcmp(prop_name, "getlastmodified")) {
1414			//buffer_append_string_len(b,CONST_STR_LEN("<D:getlastmodified ns0:dt=\"dateTime.rfc1123\">"));
1415			buffer_append_string_len(b,CONST_STR_LEN("<D:getlastmodified>"));
1416			strftime(mtime_buf, sizeof(mtime_buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(sce->st.st_mtime)));
1417			//strftime(mtime_buf, sizeof(mtime_buf), "%Y/%m/%d %H:%M:%S", localtime(&(sce->st.st_mtime)));
1418
1419			buffer_append_string(b, mtime_buf);
1420			buffer_append_string_len(b, CONST_STR_LEN("</D:getlastmodified>"));
1421			found = 1;
1422		} else if (0 == strcmp(prop_name, "getcontentlength")) {
1423			buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlength>"));
1424			buffer_append_int(b, sce->st.st_size);
1425			buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlength>"));
1426			found = 1;
1427		} else if (0 == strcmp(prop_name, "getcontentlanguage")) {
1428			buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlanguage>"));
1429			buffer_append_string_len(b, CONST_STR_LEN("en"));
1430			buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlanguage>"));
1431			found = 1;
1432		}else if (0 == strcmp(prop_name, "getuniqueid")) {
1433			//- 20120104 Jerry add
1434			buffer_append_string_len(b,CONST_STR_LEN("<D:getuniqueid>"));
1435			//Cdbg( DBE, "dst->rel_path->ptr=%s, sce->st.st_ino=%d", dst->rel_path->ptr, sce->st.st_ino );
1436
1437			char* result;
1438			md5String(dst->rel_path->ptr, NULL, &result);
1439			buffer_append_string(b, result);
1440			free(result);
1441
1442			buffer_append_string_len(b, CONST_STR_LEN("</D:getuniqueid>"));
1443			found = 1;
1444		}else if (0 == strcmp(prop_name, "getattr")) {
1445			//- 20120215 Jerry add
1446			buffer_append_string_len(b,CONST_STR_LEN("<D:getattr>"));
1447
1448			buffer_append_string_len(b, CONST_STR_LEN("<D:readonly>"));
1449			if( (sce->st.st_mode & 0x01) != 0 &&S_ISREG(sce->st.st_mode)){
1450				//Cdbg(DBE, "2222222222222222222222 %s is readonly %X", dst->path->ptr, (sce->st.st_mode & 0x01));
1451				buffer_append_string_len(b, CONST_STR_LEN("true"));
1452			}
1453			else
1454				buffer_append_string_len(b, CONST_STR_LEN("false"));
1455			buffer_append_string_len(b, CONST_STR_LEN("</D:readonly>"));
1456
1457
1458			buffer_append_string_len(b, CONST_STR_LEN("<D:hidden>"));
1459			if( (sce->st.st_mode & 0x02) != 0 &&S_ISREG(sce->st.st_mode)){
1460				//Cdbg(DBE, "1111111111111111111111 %s is hidden %X", dst->path->ptr, (sce->st.st_mode & 0x02));
1461				buffer_append_string_len(b, CONST_STR_LEN("true"));
1462			}
1463			else
1464				buffer_append_string_len(b, CONST_STR_LEN("false"));
1465			buffer_append_string_len(b, CONST_STR_LEN("</D:hidden>"));
1466
1467			/*
1468			if( (sce->st.st_mode & 0x02) != 0 )
1469				Cdbg(DBE, "1111111111111111111111 %s is hidden %X", dst->path->ptr, (sce->st.st_mode & 0x02));
1470
1471			//if( (sce->st.st_mode & 0x04) != 0 )
1472			//	Cdbg(DBE, "1111111111111111111111 %s is system %X", dst->path->ptr, (sce->st.st_mode & 0x04));
1473
1474			if( (sce->st.st_mode & 0x01) != 0 )
1475				Cdbg(DBE, "2222222222222222222222 %s is readonly %X", dst->path->ptr, (sce->st.st_mode & 0x01));
1476			*/
1477
1478			buffer_append_string_len(b, CONST_STR_LEN("</D:getattr>"));
1479			found = 1;
1480		}
1481	}
1482
1483	return found ? 0 : -1;
1484}
1485
1486static int smbdav_get_property(server *srv, connection *con, plugin_data *p, physical *dst, char *prop_name, char *prop_ns, buffer *b) {
1487
1488	if (0 == strcmp(prop_ns, "DAV:")) {
1489		/* a local 'live' property */
1490
1491		return smbdav_get_live_property(srv, con, p, dst, prop_name, b);
1492	} else {
1493		int found = 0;
1494#ifdef USE_PROPPATCH
1495		sqlite3_stmt *stmt = p->conf.stmt_select_prop;
1496
1497		if (stmt) {
1498			/* perhaps it is in sqlite3 */
1499			sqlite3_reset(stmt);
1500
1501			/* bind the values to the insert */
1502
1503			sqlite3_bind_text(stmt, 1,
1504					  dst->rel_path->ptr,
1505					  dst->rel_path->used - 1,
1506					  SQLITE_TRANSIENT);
1507			sqlite3_bind_text(stmt, 2,
1508					  prop_name,
1509					  strlen(prop_name),
1510					  SQLITE_TRANSIENT);
1511			sqlite3_bind_text(stmt, 3,
1512					  prop_ns,
1513					  strlen(prop_ns),
1514					  SQLITE_TRANSIENT);
1515
1516			/* it is the PK */
1517			while (SQLITE_ROW == sqlite3_step(stmt)) {
1518				/* there is a row for us, we only expect a single col 'value' */
1519				smbdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(stmt, 0), b);
1520				found = 1;
1521			}
1522		}
1523#endif
1524		return found ? 0 : -1;
1525	}
1526
1527	/* not found */
1528	return -1;
1529}
1530
1531typedef struct {
1532	char *ns;
1533	char *prop;
1534} smbdav_property;
1535
1536smbdav_property smbdav_live_properties[] = {
1537	{ "DAV:", "creationdate" },
1538	{ "DAV:", "displayname" },
1539	{ "DAV:", "getcontentlanguage" },
1540	{ "DAV:", "getcontentlength" },
1541	{ "DAV:", "getcontenttype" },
1542	{ "DAV:", "getetag" },
1543	{ "DAV:", "getlastmodified" },
1544	{ "DAV:", "resourcetype" },
1545	{ "DAV:", "lockdiscovery" },
1546	{ "DAV:", "source" },
1547	{ "DAV:", "supportedlock" },
1548	{ "DAV:", "getmac" },
1549	{ "DAV:", "getip" },
1550	{ "DAV:", "getonline" },
1551	{ "DAV:", "getuniqueid" },
1552	{ "DAV:", "gettype" },
1553	{ "DAV:", "getattr" },
1554	{ "DAV:", "getname" },
1555	{ "DAV:", "getpath" },
1556	{ "DAV:", "getuseragent" },
1557
1558	{ NULL, NULL }
1559};
1560
1561typedef struct {
1562	smbdav_property **ptr;
1563
1564	size_t used;
1565	size_t size;
1566} smbdav_properties;
1567
1568static int smbdav_get_props(server *srv, connection *con, plugin_data *p, physical *dst, smbdav_properties *props, buffer *b_200, buffer *b_404) {
1569	size_t i;
1570
1571	if (props) {
1572		for (i = 0; i < props->used; i++) {
1573			smbdav_property *prop;
1574			prop = props->ptr[i];
1575			if (0 != smbdav_get_property(srv, con, p, dst, prop->prop, prop->ns, b_200)) {
1576				smbdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404);
1577			}
1578		}
1579	} else {
1580		for (i = 0; smbdav_live_properties[i].prop; i++) {
1581			/* a local 'live' property */
1582			smbdav_get_live_property(srv, con, p, dst, smbdav_live_properties[i].prop, b_200);
1583		}
1584	}
1585
1586	return 0;
1587}
1588
1589#ifdef USE_PROPPATCH
1590static int smbdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p, chunkqueue *cq, xmlDoc **ret_xml) {
1591	xmlParserCtxtPtr ctxt;
1592	xmlDoc *xml;
1593	int res;
1594	int err;
1595
1596	chunk *c;
1597
1598	UNUSED(con);
1599
1600	/* read the chunks in to the XML document */
1601	ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
1602
1603	for (c = cq->first; cq->bytes_out != cq->bytes_in; c = cq->first) {
1604		size_t weWant = cq->bytes_out - cq->bytes_in;
1605		size_t weHave;
1606
1607		switch(c->type) {
1608		case SMB_CHUNK:
1609			break;
1610		case FILE_CHUNK:
1611			weHave = c->file.length - c->offset;
1612
1613			if (weHave > weWant) weHave = weWant;
1614
1615			/* xml chunks are always memory, mmap() is our friend */
1616			if (c->file.mmap.start == MAP_FAILED) {
1617				if (-1 == c->file.fd &&  /* open the file if not already open */
1618				    -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
1619					log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
1620
1621					return -1;
1622				}
1623
1624				if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
1625					log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
1626							strerror(errno), c->file.name,  c->file.fd);
1627					close(c->file.fd);
1628					c->file.fd = -1;
1629
1630					return -1;
1631				}
1632
1633				close(c->file.fd);
1634				c->file.fd = -1;
1635
1636				c->file.mmap.length = c->file.length;
1637
1638				/* chunk_reset() or chunk_free() will cleanup for us */
1639			}
1640
1641			if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) {
1642				log_error_write(srv, __FILE__, __LINE__, "sodd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
1643			}
1644
1645			c->offset += weHave;
1646			cq->bytes_out += weHave;
1647
1648			break;
1649		case MEM_CHUNK:
1650			/* append to the buffer */
1651			weHave = c->mem->used - 1 - c->offset;
1652
1653			if (weHave > weWant) weHave = weWant;
1654
1655			if (p->conf.log_xml) {
1656				log_error_write(srv, __FILE__, __LINE__, "ss", "XML-request-body:", c->mem->ptr + c->offset);
1657			}
1658
1659			if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) {
1660				log_error_write(srv, __FILE__, __LINE__, "sodd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
1661			}
1662
1663			c->offset += weHave;
1664			cq->bytes_out += weHave;
1665
1666			break;
1667		case UNUSED_CHUNK:
1668			break;
1669		}
1670		chunkqueue_remove_finished_chunks(cq);
1671	}
1672
1673	switch ((err = xmlParseChunk(ctxt, 0, 0, 1))) {
1674	case XML_ERR_DOCUMENT_END:
1675	case XML_ERR_OK:
1676		break;
1677	default:
1678		log_error_write(srv, __FILE__, __LINE__, "sd", "xmlParseChunk failed at final packet:", err);
1679		break;
1680	}
1681
1682	xml = ctxt->myDoc;
1683	res = ctxt->wellFormed;
1684	xmlFreeParserCtxt(ctxt);
1685
1686	if (res == 0) {
1687		xmlFreeDoc(xml);
1688	} else {
1689		*ret_xml = xml;
1690	}
1691
1692	return res;
1693}
1694#endif
1695
1696#ifdef USE_LOCKS
1697static int smbdav_lockdiscovery(server *srv, connection *con,
1698		buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
1699
1700	buffer *b = buffer_init();
1701
1702	response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
1703
1704	response_header_overwrite(srv, con,
1705		CONST_STR_LEN("Content-Type"),
1706		CONST_STR_LEN("text/xml; charset=\"utf-8\""));
1707
1708	buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
1709
1710	buffer_append_string_len(b,CONST_STR_LEN("<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"));
1711	buffer_append_string_len(b,CONST_STR_LEN("<D:lockdiscovery>\n"));
1712	buffer_append_string_len(b,CONST_STR_LEN("<D:activelock>\n"));
1713
1714	buffer_append_string_len(b,CONST_STR_LEN("<D:lockscope>"));
1715	buffer_append_string_len(b,CONST_STR_LEN("<D:"));
1716	buffer_append_string(b, lockscope);
1717	buffer_append_string_len(b, CONST_STR_LEN("/>"));
1718	buffer_append_string_len(b,CONST_STR_LEN("</D:lockscope>\n"));
1719
1720	buffer_append_string_len(b,CONST_STR_LEN("<D:locktype>"));
1721	buffer_append_string_len(b,CONST_STR_LEN("<D:"));
1722	buffer_append_string(b, locktype);
1723	buffer_append_string_len(b, CONST_STR_LEN("/>"));
1724	buffer_append_string_len(b,CONST_STR_LEN("</D:locktype>\n"));
1725
1726	buffer_append_string_len(b,CONST_STR_LEN("<D:depth>"));
1727	buffer_append_string(b, depth == 0 ? "0" : "infinity");
1728	buffer_append_string_len(b,CONST_STR_LEN("</D:depth>\n"));
1729
1730	buffer_append_string_len(b,CONST_STR_LEN("<D:timeout>"));
1731	buffer_append_string_len(b, CONST_STR_LEN("Second-600"));
1732	buffer_append_string_len(b,CONST_STR_LEN("</D:timeout>\n"));
1733
1734	buffer_append_string_len(b,CONST_STR_LEN("<D:owner>"));
1735	buffer_append_string_len(b,CONST_STR_LEN("</D:owner>\n"));
1736
1737	buffer_append_string_len(b,CONST_STR_LEN("<D:locktoken>"));
1738	buffer_append_string_len(b, CONST_STR_LEN("<D:href>"));
1739	buffer_append_string_buffer(b, locktoken);
1740	buffer_append_string_len(b, CONST_STR_LEN("</D:href>"));
1741	buffer_append_string_len(b,CONST_STR_LEN("</D:locktoken>\n"));
1742
1743	buffer_append_string_len(b,CONST_STR_LEN("</D:activelock>\n"));
1744	buffer_append_string_len(b,CONST_STR_LEN("</D:lockdiscovery>\n"));
1745	buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
1746
1747	chunkqueue_append_buffer(con->write_queue, b);
1748	buffer_free(b);
1749
1750	return 0;
1751}
1752#endif
1753
1754/**
1755 * check if resource is having the right locks to access to resource
1756 *
1757 *
1758 *
1759 */
1760static int smbdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
1761	int has_lock = 1;
1762
1763#ifdef USE_LOCKS
1764	data_string *ds;
1765	UNUSED(srv);
1766
1767	/**
1768	 * This implementation is more fake than real
1769	 * we need a parser for the If: header to really handle the full scope
1770	 *
1771	 * X-Litmus: locks: 11 (owner_modify)
1772	 * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>)
1773	 * - a tagged check:
1774	 *   if http://127.0.0.1:1025/dav/litmus/lockme is locked with
1775	 *   opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1, go on
1776	 *
1777	 * X-Litmus: locks: 16 (fail_cond_put)
1778	 * If: (<DAV:no-lock> ["-1622396671"])
1779	 * - untagged:
1780	 *   go on if the resource has the etag [...] and the lock
1781	 */
1782	if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
1783		/* Ooh, ooh. A if tag, now the fun begins.
1784		 *
1785		 * this can only work with a real parser
1786		 **/
1787	} else {
1788		/* we didn't provided a lock-token -> */
1789		/* if the resource is locked -> 423 */
1790
1791		sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
1792
1793		sqlite3_reset(stmt);
1794
1795		sqlite3_bind_text(stmt, 1,
1796			  CONST_BUF_LEN(uri),
1797			  SQLITE_TRANSIENT);
1798
1799		while (SQLITE_ROW == sqlite3_step(stmt)) {
1800			has_lock = 0;
1801		}
1802	}
1803#else
1804	UNUSED(srv);
1805	UNUSED(con);
1806	UNUSED(p);
1807	UNUSED(uri);
1808#endif
1809
1810	return has_lock;
1811}
1812
1813static int smbdav_get_share_property(server *srv, connection *con,
1814	plugin_data *p,
1815	physical *dst,
1816	buffer *ip,
1817	buffer *mac,
1818	int online,
1819	int type,
1820	char *prop_name,
1821	buffer *b)
1822{
1823	int found = 0;
1824
1825	UNUSED(p);
1826
1827	//if (HANDLER_ERROR != (smb_cache_get_entry(srv, con, p, dst->path, &sce)))
1828	{
1829		char ctime_buf[] = "2005-08-18T07:27:16Z";
1830		char mtime_buf[] = "Thu, 18 Aug 2005 07:27:16 GMT";
1831		size_t k;
1832
1833		if (0 == strcmp(prop_name, "resourcetype")) {
1834			buffer_append_string_len(b, CONST_STR_LEN("<D:resourcetype><D:collection/></D:resourcetype>"));
1835			found = 1;
1836		} else if (0 == strcmp(prop_name, "getcontenttype")) {
1837			buffer_append_string_len(b, CONST_STR_LEN("<D:getcontenttype>httpd/unix-directory</D:getcontenttype>"));
1838			found = 1;
1839#if 0
1840		} else if (0 == strcmp(prop_name, "creationdate")) {
1841			buffer_append_string_len(b, CONST_STR_LEN("<D:creationdate ns0:dt=\"dateTime.tz\">"));
1842			strftime(ctime_buf, sizeof(ctime_buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&(sce->st.st_ctime)));
1843			buffer_append_string(b, ctime_buf);
1844			buffer_append_string_len(b, CONST_STR_LEN("</D:creationdate>"));
1845			found = 1;
1846		} else if (0 == strcmp(prop_name, "getlastmodified")) {
1847			buffer_append_string_len(b,CONST_STR_LEN("<D:getlastmodified ns0:dt=\"dateTime.rfc1123\">"));
1848			strftime(mtime_buf, sizeof(mtime_buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(sce->st.st_mtime)));
1849			buffer_append_string(b, mtime_buf);
1850			buffer_append_string_len(b, CONST_STR_LEN("</D:getlastmodified>"));
1851			found = 1;
1852		} else if (0 == strcmp(prop_name, "getcontentlength")) {
1853			buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlength>"));
1854			buffer_append_off_t(b, sce->st.st_size);
1855			buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlength>"));
1856			found = 1;
1857#endif
1858		} else if (0 == strcmp(prop_name, "getcontentlanguage")) {
1859			buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlanguage>"));
1860			buffer_append_string_len(b, CONST_STR_LEN("en"));
1861			buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlanguage>"));
1862			found = 1;
1863		}else if (0 == strcmp(prop_name, "getmac")) {
1864			//- 20111124 Jerry add
1865			buffer_append_string_len(b,CONST_STR_LEN("<D:getmac>"));
1866			if(mac && mac->used)
1867				buffer_append_string_buffer(b, mac);
1868			buffer_append_string_len(b, CONST_STR_LEN("</D:getmac>"));
1869			found = 1;
1870		}else if (0 == strcmp(prop_name, "getip")) {
1871			//- 20120417 Jerry add
1872			buffer_append_string_len(b,CONST_STR_LEN("<D:getip>"));
1873			if(ip && ip->used)
1874				buffer_append_string_buffer(b, ip);
1875			buffer_append_string_len(b, CONST_STR_LEN("</D:getip>"));
1876			found = 1;
1877		}else if (0 == strcmp(prop_name, "getonline")) {
1878			//- 20111219 Jerry add
1879			buffer_append_string_len(b,CONST_STR_LEN("<D:getonline>"));
1880			char char_status[5]="\0";
1881			sprintf(char_status, "%d", online);
1882			buffer_append_string(b, char_status);
1883			buffer_append_string_len(b, CONST_STR_LEN("</D:getonline>"));
1884			found = 1;
1885		}else if (0 == strcmp(prop_name, "getuniqueid")) {
1886			//- 20120104 Jerry add
1887			buffer_append_string_len(b,CONST_STR_LEN("<D:getuniqueid>"));
1888			char* result;
1889			md5String(dst->rel_path->ptr, ( (mac && mac->used) ? mac->ptr : NULL ), &result);
1890			buffer_append_string(b, result);
1891			free(result);
1892			buffer_append_string_len(b, CONST_STR_LEN("</D:getuniqueid>"));
1893			found = 1;
1894		}else if (0 == strcmp(prop_name, "gettype")) {
1895			//- 20120208 Jerry add
1896			buffer_append_string_len(b,CONST_STR_LEN("<D:gettype>"));
1897			if(type==1)
1898				buffer_append_string(b, "sambapc");
1899			else if( type==2)
1900				buffer_append_string(b, "usbdisk");
1901			else
1902				buffer_append_string(b, "unknown");
1903			buffer_append_string_len(b, CONST_STR_LEN("</D:gettype>"));
1904			found = 1;
1905		}else if (0 == strcmp(prop_name, "getuseragent")) {
1906			//- 20121205 Jerry add
1907			buffer_append_string_len(b,CONST_STR_LEN("<D:getuseragent>"));
1908			if(con->smb_info){
1909				buffer_append_string_buffer(b, con->smb_info->user_agent);
1910			}
1911			buffer_append_string_len(b, CONST_STR_LEN("</D:getuseragent>"));
1912			found = 1;
1913		}
1914		/*else if (0 == strcmp(prop_name, "getname")) {
1915			//- 20120920 Jerry add
1916			buffer_append_string_len(b,CONST_STR_LEN("<D:getname>"));
1917			buffer_append_string_len(b,CONST_STR_LEN("sda"));
1918			buffer_append_string_len(b, CONST_STR_LEN("</D:getname>"));
1919			found = 1;
1920		}else if (0 == strcmp(prop_name, "getpath")) {
1921			//- 20120920 Jerry add
1922			Cdbg(1, "qqqqqqqqqqqqqq %s", dst->rel_path->ptr);
1923			buffer_append_string_len(b,CONST_STR_LEN("<D:getpath>"));
1924			buffer_append_string_buffer(b,dst->rel_path);
1925			buffer_append_string_len(b, CONST_STR_LEN("</D:getpath>"));
1926			found = 1;
1927		}*/
1928	}
1929
1930	return found ? 0 : -1;
1931}
1932
1933static int smbdav_get_share_props(server *srv, connection *con,
1934	plugin_data *p,
1935	physical *dst,
1936	buffer *ip,
1937	buffer *mac,
1938	int online,
1939	int type,
1940	smbdav_properties *props,
1941	buffer *b_200,
1942	buffer *b_404)
1943{
1944	size_t i;
1945
1946	if (props) {
1947		for (i = 0; i < props->used; i++) {
1948			smbdav_property *prop;
1949			prop = props->ptr[i];
1950			if (0 != smbdav_get_share_property(srv, con, p, dst, ip, mac, online, type, prop->prop, b_200)) {
1951				smbdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_200);
1952			}
1953		}
1954
1955		if(props->used==0){
1956			for (i = 0; smbdav_live_properties[i].prop; i++) {
1957				if (0 != smbdav_get_share_property(srv, con, p, dst, ip, mac, online, type, smbdav_live_properties[i].prop, b_200)) {
1958					smbdav_gen_prop_tag(srv, con, smbdav_live_properties[i].prop, smbdav_live_properties[i].ns, NULL, b_200);
1959				}
1960			}
1961		}
1962
1963	} else {
1964		for (i = 0; smbdav_live_properties[i].prop; i++) {
1965			/* a local 'live' property */
1966			smbdav_get_share_property(srv, con, p, dst, ip, mac, online, type, smbdav_live_properties[i].prop, b_200);
1967		}
1968	}	return 0;
1969}
1970
1971 void smbdav_propfind_prepare_response_bulk(server *srv, connection *con, plugin_data *p,
1972	buffer *b, physical *d, buffer *prop_200, buffer *prop_404)
1973{
1974	buffer_append_string_len(b,CONST_STR_LEN("<D:response>\n"));
1975	buffer_append_string_len(b,CONST_STR_LEN("<D:href>"));
1976	buffer_append_string_buffer(b, con->uri.scheme);
1977	buffer_append_string_len(b,CONST_STR_LEN("://"));
1978	buffer_append_string_buffer(b, con->uri.authority);
1979
1980	if( con->share_link_shortpath->used ){
1981		char buff[4096];
1982		char* tmp = replace_str(&d->rel_path->ptr[0],
1983			                    (char*)con->share_link_realpath->ptr,
1984			                    (char*)con->share_link_shortpath->ptr,
1985				                (char *)&buff[0]);
1986
1987		buffer_append_string(b, "/");
1988		buffer_append_string_encoded(b, tmp, strlen(tmp), ENCODING_REL_URI);
1989	}
1990	else{
1991		//- 20111227
1992		buffer_append_string_encoded(b, CONST_BUF_LEN(d->rel_path), ENCODING_REL_URI);
1993	}
1994
1995	buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
1996
1997	if (!buffer_is_empty(prop_200)) {
1998		buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
1999		buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
2000
2001		buffer_append_string_buffer(b, prop_200);
2002
2003		buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
2004
2005		buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 200 OK</D:status>\n"));
2006
2007		buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
2008	}
2009	if (!buffer_is_empty(prop_404)) {
2010		buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
2011		buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
2012
2013		buffer_append_string_buffer(b, prop_404);
2014
2015		buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
2016
2017		buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 404 Not Found</D:status>\n"));
2018
2019		buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
2020	}
2021
2022	buffer_append_string_len(b,CONST_STR_LEN("</D:response>\n"));
2023
2024	return;
2025
2026}
2027
2028int smbc_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir)
2029{
2030	int dh;
2031	buffer *out;
2032	data_string *ds_userAgent = (data_string *)array_get_element(con->request.headers, "user-Agent");
2033
2034	out = buffer_init();
2035
2036	buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
2037	buffer_append_string_len(out, CONST_STR_LEN("utf-8"));
2038	buffer_append_string_len(out, CONST_STR_LEN("\"?>\n"));
2039#if 1
2040	/*
2041	if( ds_userAgent &&
2042		( //strstr( ds_userAgent->value->ptr, "Chrome" ) ||
2043		  strstr( ds_userAgent->value->ptr, "iPhone" ) ||
2044		  strstr( ds_userAgent->value->ptr, "iPad"   ) ||
2045		  strstr( ds_userAgent->value->ptr, "iPod"   ) ||
2046		  strstr( ds_userAgent->value->ptr, "Android") ) ){
2047	*/
2048	if(buffer_is_equal_string(con->uri.query, CONST_STR_LEN("mobile=1"))){
2049		buffer_append_string_len(out, CONST_STR_LEN(
2050				"<!DOCTYPE html>\n"
2051				"<html>\n"
2052				"<head>\n"
2053				"<meta charset=\"utf-8\"/>\n"
2054				"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
2055				"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\" />"
2056				"<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n"
2057				"<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n"
2058				"<link rel=\"apple-touch-icon\" href=\"/smb/css/appicon.png\">\n"
2059				"<link rel=\"apple-touch-startup-image\" href=\"/smb/css/startup.png\">\n"
2060				"<title>AiCloud</title>\n"
2061			));
2062
2063
2064		//- Mobile UI
2065		buffer_append_string_len(out, CONST_STR_LEN(
2066				"<link rel='stylesheet' id='mainCss' href='/smb/css/style-theme1.app.css' type='text/css'/>\n"
2067				"<script type='text/javascript' src='/smb/js/tools.app.js'></script>\n"
2068				"<script type='text/javascript' src='/smb/js/davclient_tools.js'></script>\n"
2069				"<script type='text/javascript' src='/smb/js/smbdav-main.app.min.js'></script>\n"
2070			));
2071
2072		buffer_append_string_len(out, CONST_STR_LEN("</head>"));
2073		buffer_append_string_len(out, CONST_STR_LEN("<body class='ui-mobile-viewport ui-overlay-c'>"));
2074
2075		buffer_append_string_len(out, CONST_STR_LEN("<div id='mainpage' data-role='page' data-theme='a' data-fullscreen='false'>"));
2076
2077		//- header
2078		buffer_append_string_len(out, CONST_STR_LEN("<div id='header' data-role='header' data-position='fixed'>"));
2079		buffer_append_string_len(out, CONST_STR_LEN("<div id='light'></div>"));
2080		buffer_append_string_len(out, CONST_STR_LEN("<span id='title-logo'>ASUS AiCloud</span>"));
2081		buffer_append_string_len(out, CONST_STR_LEN("<span id='title-welcome'>Welcome home, <span id='username'>admin</span></span>"));
2082		buffer_append_string_len(out, CONST_STR_LEN("<div id='options'>"));
2083		buffer_append_string_len(out, CONST_STR_LEN("<div id='btn-changeuser' class='bicon'></div>"));
2084		buffer_append_string_len(out, CONST_STR_LEN("<div id='btn-select' class='bicon'></div>"));
2085		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2086		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2087
2088		//- content
2089		buffer_append_string_len(out, CONST_STR_LEN("<div id='content' data-role='content'>"));
2090		buffer_append_string_len(out, CONST_STR_LEN("<ul data-role='listview' id='list' data-inset='false'>"));
2091		buffer_append_string_len(out, CONST_STR_LEN("</ul>"));
2092		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2093
2094		//- footer
2095		buffer_append_string_len(out, CONST_STR_LEN("<div id='footer' data-role='footer' data-position='fixed'>"));
2096		buffer_append_string_len(out, CONST_STR_LEN("<div id='navbar' data-role='navbar' style='display:block'>"));
2097		buffer_append_string_len(out, CONST_STR_LEN("<ul>"));
2098		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-home' href='#' data-role='button' data-icon='cloud-home' data-iconpos='top' data-corners='false'>Home</a>"));
2099		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-refresh' href='#' data-role='button' data-icon='cloud-refresh' data-iconpos='top' data-corners='false'>Refresh</a>"));
2100		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-logout' href='#' data-role='button' data-icon='cloud-logout' data-iconpos='top' data-corners='false'>Logout</a>"));
2101		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-setting' href='#' data-role='button' data-icon='cloud-setting' data-iconpos='top' data-corners='false'>Setting</a>"));
2102		buffer_append_string_len(out, CONST_STR_LEN("</ul>"));
2103		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2104		buffer_append_string_len(out, CONST_STR_LEN("<div id='navbar2' data-role='navbar' style='display:none'>"));
2105		buffer_append_string_len(out, CONST_STR_LEN("<ul>"));
2106		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-delete' href='#' data-role='button' data-icon='cloud-delete' data-iconpos='top' data-corners='false'>Delete</a>"));
2107		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-rename' href='#' data-role='button' data-icon='cloud-rename' data-iconpos='top' data-corners='false'>Rename</a>"));
2108		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-share' href='#' data-role='button' data-icon='cloud-share' data-iconpos='top' data-corners='false'>Share</a>"));
2109		buffer_append_string_len(out, CONST_STR_LEN("<li><a id='btn-createfolder' href='#' data-role='button' data-icon='cloud-createfolder' data-iconpos='top' data-corners='false'>Add Folder</a>"));
2110		buffer_append_string_len(out, CONST_STR_LEN("</ul>"));
2111		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2112		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2113
2114		buffer_append_string_len(out, CONST_STR_LEN("</div>"));
2115
2116		buffer_append_string_len(out, CONST_STR_LEN("</body>"));
2117	}
2118	else
2119#endif
2120	{
2121		buffer_append_string_len(out, CONST_STR_LEN(
2122			"<!DOCTYPE html>\n"
2123			"<html>\n"
2124			"<head>\n"
2125			"<meta charset=\"utf-8\"/>\n"
2126			"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
2127                        "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n"
2128			//"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
2129			//"<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n"
2130			//"<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n"
2131			//"<link rel=\"apple-touch-icon\" href=\"/smb/css/appicon.png\">\n"
2132			//"<link rel=\"apple-touch-startup-image\" href=\"/smb/css/startup.png\">\n"
2133			"<title>AiCloud</title>\n"
2134		));
2135
2136		//- General UI
2137		buffer_append_string_len(out, CONST_STR_LEN(
2138				"<link rel='stylesheet' id='mainCss' href='/smb/css/style-theme.css' type='text/css'/>\n"
2139				"<link rel='stylesheet' id='mainCss' href='/smb/css/jplayer.blue.monday.css' type='text/css'/>\n"
2140				"<script type='text/javascript' src='/smb/js/tools.js'></script>\n"
2141				"<script type='text/javascript' src='/smb/js/davclient_tools.js'></script>\n"
2142				"<script type='text/javascript' src='/smb/js/smbdav-main.min.js'></script>\n"
2143			));
2144
2145		if( buffer_is_equal_string(con->url.rel_path, CONST_STR_LEN("/"))){
2146			buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body></body>\n"));
2147		}
2148		else{
2149			buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body openurl='"));
2150			buffer_append_string( out, con->url.rel_path->ptr );
2151			buffer_append_string_len(out, CONST_STR_LEN("' fileview_only='1'></body>\n"));
2152		}
2153	}
2154
2155	/* Insert possible charset to Content-Type */
2156	response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html; charset=UTF-8"));
2157
2158	chunkqueue_append_buffer(con->write_queue, out);
2159	buffer_free(out);
2160
2161	con->file_finished = 1;
2162
2163	return 0;
2164}
2165
2166int smbc_list_host(server *srv, connection *con,
2167	smbdav_properties *req_props,
2168	plugin_data *p, buffer *b,
2169	buffer *prop_200,
2170	buffer *prop_404)
2171{
2172	int dir;
2173	int count = 0;
2174	smb_srv_info_t *c;
2175	physical d;
2176	physical *dst = &con->url;
2177
2178#ifdef SCAN_MASTER_BROWSER
2179	//- Count samba server
2180	for (c = smb_srv_info_list; c; c = c->next) {
2181		count++;
2182	}
2183
2184	if(count<=0){
2185		if (NULL != (dir = smbc_wrapper_opendir(con, con->url.path->ptr))) {
2186			struct smbc_dirent *de;
2187			physical d;
2188
2189			d.path = buffer_init();
2190			d.rel_path = buffer_init();
2191
2192			while(NULL != (de = smbc_wrapper_readdir(con, dir))) {
2193				char workgroup[100];
2194				DIR *subdir;
2195				struct smbc_dirent *subde;
2196				sprintf(workgroup, "smb://%s/", de->name);
2197
2198				if (NULL != (subdir = smbc_wrapper_opendir(con, workgroup))) {
2199					while(NULL != (subde = smbc_wrapper_readdir(con, subdir))) {
2200
2201						buffer_copy_buffer(d.path, dst->path);
2202						buffer_append_slash(d.path);
2203
2204						buffer_copy_buffer(d.rel_path, dst->rel_path);
2205						buffer_append_slash(d.rel_path);
2206
2207						if (subde->name[0] == '.' && subde->name[1] == '\0') {
2208								/* don't append the . */
2209						} else {
2210							buffer_append_string(d.path, subde->name);
2211							buffer_append_string(d.rel_path, subde->name);
2212						}
2213
2214						buffer_reset(prop_200);
2215						buffer_reset(prop_404);
2216
2217						smbdav_get_share_props(srv, con, p, &d, NULL, NULL, 0, 1, req_props, prop_200, prop_404);
2218						smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
2219					}
2220					smbc_wrapper_closedir(con, subdir);
2221				}
2222			}
2223			smbc_wrapper_closedir(con, dir);
2224			buffer_free(d.path);
2225			buffer_free(d.rel_path);
2226		}
2227
2228		return 0;
2229	}
2230#endif
2231
2232	d.path = buffer_init();
2233	d.rel_path = buffer_init();
2234
2235	//- 20111209 Jerry add
2236	//- Add usbdisk
2237	char *usbdisk_name;
2238#if EMBEDDED_EANBLE
2239	char *a = nvram_get_productid();
2240	int l = strlen(a)+1;
2241	usbdisk_name = (char*)malloc(l);
2242	memset(usbdisk_name,'\0', l);
2243	strcpy(usbdisk_name, a);
2244	#ifdef APP_IPKG
2245	free(a);
2246	#endif
2247#else
2248	usbdisk_name = (char*)malloc(8);
2249	memset(usbdisk_name,'\0', 8);
2250	strcpy(usbdisk_name, "usbdisk");
2251#endif
2252
2253	if( is_usbdisk_exist( srv, con, usbdisk_name ) == 1 ){
2254#if EMBEDDED_EANBLE
2255		disk_info_t *disks_info, *follow_disk;
2256		partition_info_t *follow_partition;
2257		char *Ptr;
2258
2259		disks_info = read_disk_data();
2260	    if (disks_info != NULL){
2261
2262	        for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
2263				for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
2264					if (follow_partition->mount_point == NULL){
2265						continue;
2266					}
2267
2268					Ptr = rindex(follow_partition->mount_point, '/');
2269
2270					if (Ptr == NULL){
2271						continue;
2272					}
2273
2274					++Ptr;
2275
2276					if ( check_skip_folder_name(Ptr) == 1 ) {
2277						continue;
2278					}
2279
2280					buffer_copy_string(d.path, usbdisk_name);
2281					buffer_append_slash(d.path);
2282
2283					buffer_copy_string(d.rel_path, "/");
2284					buffer_append_string(d.rel_path, usbdisk_name);
2285					buffer_append_slash(d.rel_path);
2286
2287					buffer_append_string(d.path, Ptr);
2288					buffer_append_string(d.rel_path, Ptr);
2289
2290					Cdbg(1,"path=%s, rel_path=%s", d.path->ptr, d.rel_path->ptr);
2291					buffer* buffer_ip = buffer_init();
2292					char ip[16]="\0";
2293
2294					buffer* buffer_mac = buffer_init();
2295#if EMBEDDED_EANBLE
2296					char* mac = nvram_get_router_mac();
2297					buffer_copy_string(buffer_mac, mac);
2298
2299					#ifdef APP_IPKG
2300					if(mac) free(mac);
2301					#endif
2302#else
2303					char mac[20]="\0";
2304					get_mac_address("eth0", &mac);
2305					buffer_copy_string(buffer_mac, mac);
2306#endif
2307
2308					buffer_reset(prop_200);
2309					buffer_reset(prop_404);
2310					smbdav_get_share_props(srv, con, p, &d, buffer_ip, buffer_mac, 1, 2, req_props, prop_200, prop_404);
2311					smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
2312
2313					buffer_free(buffer_ip);
2314					buffer_free(buffer_mac);
2315
2316				}
2317			}
2318
2319			free_disk_data(&disks_info);
2320	    }
2321#else
2322
2323		if (NULL != (dir = opendir("/mnt"))) {
2324			struct dirent *de;
2325			physical d;
2326			physical *dst = &(con->physical);
2327
2328			d.path = buffer_init();
2329			d.rel_path = buffer_init();
2330
2331			while(NULL != (de = readdir(dir))) {
2332				if ( de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0' ) {
2333					continue;
2334					/* ignore the parent dir */
2335				}
2336
2337				if ( de->d_name[0] == '.' ) {
2338					continue;
2339					/* ignore the hidden file */
2340				}
2341
2342				if ( check_skip_folder_name(de->d_name) == 1 ) {
2343					continue;
2344				}
2345
2346				buffer_copy_string(d.path, usbdisk_name);
2347				buffer_append_slash(d.path);
2348
2349				buffer_copy_string(d.rel_path, "/");
2350				buffer_append_string(d.rel_path, usbdisk_name);
2351				buffer_append_slash(d.rel_path);
2352
2353				if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
2354					/* don't append the . */
2355				} else {
2356					buffer_append_string(d.path, de->d_name);
2357					buffer_append_string(d.rel_path, de->d_name);
2358				}
2359
2360				Cdbg(1,"path=%s, rel_path=%s", d.path->ptr, d.rel_path->ptr);
2361				buffer* buffer_ip = buffer_init();
2362				char ip[16]="\0";
2363
2364				buffer* buffer_mac = buffer_init();
2365#if EMBEDDED_EANBLE
2366				char* mac = nvram_get_router_mac();
2367				buffer_copy_string(buffer_mac, mac);
2368
2369				#ifdef APP_IPKG
2370				if(mac) free(mac);
2371				#endif
2372#else
2373				char mac[20]="\0";
2374				get_mac_address("eth0", &mac);
2375				buffer_copy_string(buffer_mac, mac);
2376#endif
2377
2378				buffer_reset(prop_200);
2379				buffer_reset(prop_404);
2380				smbdav_get_share_props(srv, con, p, &d, buffer_ip, buffer_mac, 1, 2, req_props, prop_200, prop_404);
2381				smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
2382
2383				buffer_free(buffer_ip);
2384				buffer_free(buffer_mac);
2385			}
2386		}
2387#endif
2388
2389	}
2390
2391	free(usbdisk_name);
2392
2393	//- Only show usbdisk if account right is not equal 0.
2394	//if( con->smb_info->auth_right != 1 )
2395	//	return 0;
2396
2397#if EMBEDDED_EANBLE
2398	#ifndef APP_IPKG
2399	if(strcmp( nvram_get_webdavproxy(), "0" ) == 0)
2400		return 0;
2401	#else
2402	char *wwebdavproxy = nvram_get_webdavproxy();
2403    if(strcmp( wwebdavproxy, "0" ) == 0)
2404		return 0;
2405    free(wwebdavproxy);
2406	#endif
2407	char* aa = nvram_get_smbdav_str();
2408
2409	if(aa==NULL){
2410		buffer_free(d.path);
2411		buffer_free(d.rel_path);
2412		return;
2413	}
2414
2415	char* str_smbdav_list = (char*)malloc(strlen(aa)+1);
2416	strcpy(str_smbdav_list, aa);
2417	#ifdef APP_IPKG
2418	free(aa);
2419	#endif
2420	if(str_smbdav_list!=NULL){
2421		char * pch1;
2422		char * pch;
2423		pch = strtok(str_smbdav_list, "<>");
2424
2425		while(pch!=NULL){
2426
2427			char name[20], ip[20], mac[50];
2428			int name_len, ip_len, mac_len, online;
2429
2430			//- PC Name
2431			name_len = strlen(pch);
2432			strncpy(name, pch, name_len);
2433			name[name_len] = '\0';
2434			//fprintf(stderr,"name=%s\n", pch);
2435
2436			//- IP Address
2437			pch = strtok(NULL,"<>");
2438			ip_len = strlen(pch);
2439			strncpy(ip, pch, ip_len);
2440			ip[ip_len] = '\0';
2441			buffer* buffer_ip = buffer_init();
2442			buffer_copy_string(buffer_ip, ip);
2443			//fprintf(stderr,"ip=%s\n", pch);
2444
2445			//- MAC Address
2446			pch = strtok(NULL,"<>");
2447			mac_len = strlen(pch);
2448			strncpy(mac, pch, mac_len);
2449			mac[mac_len] = '\0';
2450			buffer* buffer_mac = buffer_init();
2451			buffer_copy_string(buffer_mac, mac);
2452			//fprintf(stderr,"mac=%s\n", pch);
2453
2454			//- PC Online?
2455			pch = strtok(NULL,"<>");
2456			online = atoi(pch);
2457			buffer_copy_buffer(d.path, dst->path);
2458			buffer_append_slash(d.path);
2459
2460			buffer_copy_buffer(d.rel_path, dst->rel_path);
2461			buffer_append_slash(d.rel_path);
2462
2463			buffer_append_string(d.path, name);
2464			buffer_append_string(d.rel_path, name);
2465
2466			//Cdbg(DBE, "dst->path=[%s], online=[%d]", dst->path->ptr, online);
2467			//Cdbg(DBE, "d.path=[%s], d.rel_path=[%s]", d.path->ptr, d.rel_path->ptr);
2468
2469			buffer_reset(prop_200);
2470			buffer_reset(prop_404);
2471
2472			smbdav_get_share_props(srv, con, p, &d, buffer_ip, buffer_mac, online, 1, req_props, prop_200, prop_404);
2473			smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
2474
2475			buffer_free(buffer_ip);
2476			buffer_free(buffer_mac);
2477
2478			pch = strtok(NULL,"<>");
2479			//fprintf(stderr,"next pch=%s\n\n", pch);
2480		}
2481
2482		free(str_smbdav_list);
2483	}
2484#else
2485	size_t j;
2486	int length, filesize;
2487	char* g_temp_file = "/tmp/arpping_list";
2488	FILE* fp = fopen(g_temp_file, "r");
2489	if(fp!=NULL){
2490
2491		char str[1024];
2492
2493		while(fgets(str,sizeof(str),fp) != NULL)
2494		{
2495      		// strip trailing '\n' if it exists
2496      		int len = strlen(str)-1;
2497      		if(str[len] == '\n')
2498         		str[len] = 0;
2499
2500			char name[20], ip[20], mac[50];
2501			int name_len, ip_len, mac_len, online;
2502			char * pch;
2503
2504			//- PC Name
2505			pch = strtok(str,"<");
2506			name_len = strlen(pch);
2507			strncpy(name, pch, name_len);
2508			name[name_len] = '\0';
2509
2510			//- IP Address
2511			pch = strtok(NULL,"<");
2512			ip_len = strlen(pch);
2513			strncpy(ip, pch, ip_len);
2514			ip[ip_len] = '\0';
2515			buffer* buffer_ip = buffer_init();
2516			buffer_copy_string(buffer_ip, ip);
2517
2518			//- MAC Address
2519			pch = strtok(NULL,"<");
2520			mac_len = strlen(pch);
2521			strncpy(mac, pch, mac_len);
2522			mac[mac_len] = '\0';
2523			buffer* buffer_mac = buffer_init();
2524			buffer_copy_string(buffer_mac, mac);
2525
2526			//- PC Online?
2527			pch = strtok(NULL,"<");
2528			online = atoi(pch);
2529			buffer_copy_buffer(d.path, dst->path);
2530			buffer_append_slash(d.path);
2531
2532			buffer_copy_buffer(d.rel_path, dst->rel_path);
2533			buffer_append_slash(d.rel_path);
2534
2535			buffer_append_string(d.path, name);
2536			buffer_append_string(d.rel_path, name);
2537
2538			//Cdbg(DBE, "dst->path=[%s], online=[%d]", dst->path->ptr, online);
2539			Cdbg(DBE, "d.path=[%s], d.rel_path=[%s]", d.path->ptr, d.rel_path->ptr);
2540
2541			buffer_reset(prop_200);
2542			buffer_reset(prop_404);
2543
2544			smbdav_get_share_props(srv, con, p, &d, buffer_ip, buffer_mac, online, 1, req_props, prop_200, prop_404);
2545			smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
2546
2547			//Cdbg(DBE, "b=%s", b->ptr);
2548
2549			buffer_free(buffer_ip);
2550			buffer_free(buffer_mac);
2551		}
2552
2553		fclose(fp);
2554	}
2555#endif
2556
2557	buffer_free(d.path);
2558	buffer_free(d.rel_path);
2559
2560}
2561
2562#if 0
2563void smbc_init_aicloud_db(server *srv){
2564
2565	if(is_jffs_supported()==0){
2566		return;
2567	}
2568
2569	char *err;
2570	sqlite3 *sql_aicloud;
2571	char* aicloud_db_file_path = get_aicloud_db_file_path();
2572
2573	if (SQLITE_OK != sqlite3_open(aicloud_db_file_path, &(sql_aicloud))) {
2574		log_error_write(srv, __FILE__, __LINE__, "sbs", "sqlite3_open failed for",
2575								aicloud_db_file_path,
2576								sqlite3_errmsg(sql_aicloud));
2577		Cdbg(1, "fail to open db file[%s]", aicloud_db_file_path);
2578		return;
2579	}
2580
2581	if (SQLITE_OK != sqlite3_exec(sql_aicloud,
2582			"CREATE TABLE account_info ("
2583			"  id INTEGER PRIMARY KEY AUTOINCREMENT,"
2584			"  username VARCHAR(30) NOT NULL DEFAULT '',"
2585			"  password VARCHAR(50) NOT NULL DEFAULT '',"
2586			"  name VARCHAR(20) NOT NULL DEFAULT '',"
2587			"  email VARCHAR(50) NOT NULL DEFAULT '',"
2588			"  bytes_in_avail BIGINT NOT NULL DEFAULT 0,"
2589			"  bytes_in_used BIGINT NOT NULL DEFAULT 0,"
2590			"  smart_access INT NOT NULL DEFAULT 0,"
2591			"  login_count INT NOT NULL DEFAULT 0,"
2592			"  login_fail_count INT NOT NULL DEFAULT 0,"
2593			"  auth_type TINYINT NOT NULL DEFAULT 0,"
2594			"  auth_uid BIGINT NOT NULL  DEFAULT 0"
2595			"  )",
2596			NULL, NULL, &err)) {
2597
2598		Cdbg(1, "1.err[%s]", err);
2599
2600		if (0 != strcmp(err, "table account_info already exists")) {
2601			log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
2602			sqlite3_free(err);
2603			return;
2604		}
2605
2606		sqlite3_free(err);
2607	}
2608
2609	if (SQLITE_OK != sqlite3_exec(sql_aicloud,
2610			"CREATE TABLE login_info ("
2611			"  id INTEGER PRIMARY KEY AUTOINCREMENT,"
2612			"  account_id INT NOT NULL DEFAULT 0,"
2613			"  ip VARCHAR(15) NOT NULL DEFAULT '',"
2614			"  status INT NOT NULL DEFAULT 0,"
2615			"  timestamp DATETIME DEFAULT CURRENT_TIMESTAMP"
2616			"  )",
2617			NULL, NULL, &err)) {
2618
2619		Cdbg(1, "2.err[%s]", err);
2620
2621		if (0 != strcmp(err, "table login_info already exists")) {
2622			log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
2623			sqlite3_free(err);
2624			return;
2625		}
2626
2627		sqlite3_free(err);
2628	}
2629
2630	if (SQLITE_OK != sqlite3_exec(sql_aicloud,
2631			"CREATE TABLE invite_info ("
2632			"  id INTEGER PRIMARY KEY AUTOINCREMENT,"
2633			"  productid VARCHAR(50) NOT NULL DEFAULT '',"
2634			"  deviceid VARCHAR(50) NOT NULL DEFAULT '',"
2635			"  token VARCHAR(37) NOT NULL DEFAULT '',"
2636			"  permission MEDIUMTEXT NOT NULL,"
2637			"  bytes_in_avail BIGINT NOT NULL DEFAULT 0,"
2638			"  smart_access INT NOT NULL DEFAULT 0,"
2639			"  security_code VARCHAR(10) NOT NULL DEFAULT '',"
2640			"  status INT NOT NULL DEFAULT 0,"
2641			"  auth_type TINYINT NOT NULL DEFAULT 0,"
2642			"  timestamp DATETIME DEFAULT CURRENT_TIMESTAMP"
2643			"  )",
2644			NULL, NULL, &err)) {
2645
2646		Cdbg(1, "2.err[%s]", err);
2647
2648		if (0 != strcmp(err, "table invite_info already exists")) {
2649			log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
2650			sqlite3_free(err);
2651			return;
2652		}
2653
2654		sqlite3_free(err);
2655	}
2656
2657	if (sql_aicloud) {
2658		sqlite3_close(sql_aicloud);
2659	}
2660
2661	Cdbg(1, "finish");
2662}
2663#endif
2664
2665URIHANDLER_FUNC(mod_smbdav_subrequest_handler) {
2666	plugin_data *p = p_d;
2667	buffer *b;
2668	DIR *dir;
2669	data_string *ds;
2670	int depth = -1;
2671	struct stat st;
2672	buffer *prop_200;
2673	buffer *prop_404;
2674	smbdav_properties *req_props;
2675	stat_cache_entry *sce = NULL;
2676	handler_t res = HANDLER_GO_ON;
2677
2678#if 0
2679	//UNUSED(srv);
2680	Cdbg(DBE,"enter mod_smbdav_subrequest_handler..");
2681	Cdbg(DBE, "con->physical.path = %s", con->physical.path->ptr);
2682	Cdbg(DBE, "con->uri->path = %s", con->uri.path->ptr);
2683#endif
2684
2685	if (!p->conf.enabled) {
2686		return HANDLER_GO_ON;
2687	}
2688
2689	/* physical path is setup */
2690	if (con->physical.path->used == 0) {
2691		return HANDLER_GO_ON;
2692	}
2693
2694	if (con->url.path->used == 0) {
2695		return HANDLER_GO_ON;
2696	}
2697
2698	/* PROPFIND need them */
2699	if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Depth"))) {
2700		depth = strtol(ds->value->ptr, NULL, 10);
2701	}
2702
2703	if(!con->smb_info){
2704		return HANDLER_GO_ON;
2705	}
2706
2707#if EMBEDDED_EANBLE
2708	if( !con->srv_socket->is_ssl ){
2709		if(srv->is_streaming_port_opend && con->request.http_method==HTTP_METHOD_GET){
2710		}
2711		else{
2712			con->http_status = 403;
2713			return HANDLER_FINISHED;
2714		}
2715	}
2716#endif
2717
2718	Cdbg(DBE, "http_method=[%d][%s], depth=[%d], con->smb_info->qflag=[%d]",
2719		con->request.http_method, get_http_method_name(con->request.http_method),
2720		depth,
2721		con->smb_info->qflag );
2722	Cdbg(DBE, "con->url.path = %s", con->url.path->ptr);
2723
2724	switch (con->request.http_method) {
2725	case HTTP_METHOD_OPTIONS:
2726		/* we fake a little bit but it makes MS W2k happy and it let's us mount the volume */
2727		response_header_overwrite(srv, con, CONST_STR_LEN("DAV"), CONST_STR_LEN("1,2"));
2728		response_header_overwrite(srv, con, CONST_STR_LEN("MS-Author-Via"), CONST_STR_LEN("DAV"));
2729		return HANDLER_FINISHED;
2730	case HTTP_METHOD_HEAD:
2731	      /**
2732	        * a HEAD request has the same as a GET
2733	        * without the content
2734	        */
2735		con->http_status = 200;
2736		con->file_finished = 1;
2737		chunkqueue_reset(con->write_queue);
2738		con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
2739		return HANDLER_FINISHED;
2740	case HTTP_METHOD_GET:
2741		switch(con->smb_info->qflag) {
2742		case SMB_SHARE_QUERY:
2743		case SMB_HOST_QUERY:{
2744			smbc_list_directory(srv, con, p, con->url.path);
2745			con->http_status = 200;
2746			con->file_finished = 1;
2747			joblist_append(srv, con);
2748			return HANDLER_FINISHED;
2749		}
2750
2751		case SMB_FILE_QUERY:{
2752			if (-1 == smbc_wrapper_stat(con, con->url.path->ptr, &st)) {
2753				/* don't about it yet, rmdir will fail too */
2754				return HANDLER_FINISHED;
2755			}
2756			else if (S_ISDIR(st.st_mode)) {
2757				smbc_list_directory(srv, con, p, con->url.path);
2758				con->http_status = 200;
2759				con->file_finished = 1;
2760				joblist_append(srv, con);
2761				return HANDLER_FINISHED;
2762			}
2763			else{
2764				log_sys_write(srv, "sbss", "Download samba file", con->url.rel_path, "from ip", con->dst_addr_buf->ptr);
2765				Cdbg(DBE, "METHOD_GET->SMB_FILE_QUERY: HANDLER_GO_ON, download %s", con->url.rel_path->ptr);
2766				return HANDLER_GO_ON;
2767			}
2768		}
2769
2770		default: //leave the FILE_QUERY to system default behavior
2771			return HANDLER_GO_ON;
2772		}
2773	case HTTP_METHOD_PROPFIND:
2774		/* they want to know the properties of the directory */
2775		req_props = NULL;
2776		if(con->smb_info->qflag == SMB_FILE_QUERY) {
2777			/* is there a content-body ? */
2778
2779			if( smbc_wrapper_stat(con, con->url.path->ptr, &st) < 0 ) {
2780
2781				if(errno == EACCES) {
2782					smbc_wrapper_response_401(srv, con);
2783				} else {
2784					//if (errno == ENOENT)
2785					con->http_status = 404;
2786					Cdbg(DBE, "con->http_status = 404");
2787				}
2788				return HANDLER_FINISHED;
2789			}
2790		}
2791
2792#ifdef USE_PROPPATCH
2793		/* any special requests or just allprop ? */
2794		if (con->request.content_length) {
2795			xmlDocPtr xml;
2796			if (1 == smbdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
2797
2798				xmlNode *rootnode = xmlDocGetRootElement(xml);
2799
2800				assert(rootnode);
2801
2802				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "propfind")) {
2803					xmlNode *cmd;
2804
2805					req_props = calloc(1, sizeof(*req_props));
2806
2807					for (cmd = rootnode->children; cmd; cmd = cmd->next) {
2808
2809						if (0 == xmlStrcmp(cmd->name, BAD_CAST "prop")) {
2810							/* get prop by name */
2811							xmlNode *prop;
2812
2813							for (prop = cmd->children; prop; prop = prop->next) {
2814								if (prop->type == XML_TEXT_NODE) continue; /* ignore WS */
2815
2816								if (prop->ns &&
2817								    (0 == xmlStrcmp(prop->ns->href, BAD_CAST "")) &&
2818								    (0 != xmlStrcmp(prop->ns->prefix, BAD_CAST ""))) {
2819									size_t i;
2820									log_error_write(srv, __FILE__, __LINE__, "ss",
2821											"no name space for:",
2822											prop->name);
2823
2824									xmlFreeDoc(xml);
2825
2826									for (i = 0; i < req_props->used; i++) {
2827										free(req_props->ptr[i]->ns);
2828										free(req_props->ptr[i]->prop);
2829										free(req_props->ptr[i]);
2830									}
2831									free(req_props->ptr);
2832									free(req_props);
2833
2834									con->http_status = 400;
2835									return HANDLER_FINISHED;
2836								}
2837
2838								/* add property to requested list */
2839								if (req_props->size == 0) {
2840									req_props->size = 16;
2841									req_props->ptr = malloc(sizeof(*(req_props->ptr)) * req_props->size);
2842								} else if (req_props->used == req_props->size) {
2843									req_props->size += 16;
2844									req_props->ptr = realloc(req_props->ptr, sizeof(*(req_props->ptr)) * req_props->size);
2845								}
2846
2847								req_props->ptr[req_props->used] = malloc(sizeof(smbdav_property));
2848								req_props->ptr[req_props->used]->ns = (char *)xmlStrdup(prop->ns ? prop->ns->href : (xmlChar *)"");
2849								req_props->ptr[req_props->used]->prop = (char *)xmlStrdup(prop->name);
2850
2851								req_props->used++;
2852							}
2853						} else if (0 == xmlStrcmp(cmd->name, BAD_CAST "propname")) {
2854							sqlite3_stmt *stmt = p->conf.stmt_select_propnames;
2855
2856							if (stmt) {
2857								/* get all property names (EMPTY) */
2858								sqlite3_reset(stmt);
2859								/* bind the values to the insert */
2860
2861								sqlite3_bind_text(stmt, 1,
2862										  con->uri.path->ptr,
2863										  con->uri.path->used - 1,
2864										  SQLITE_TRANSIENT);
2865
2866								if (SQLITE_DONE != sqlite3_step(stmt)) {
2867								}
2868							}
2869						} else if (0 == xmlStrcmp(cmd->name, BAD_CAST "allprop")) {
2870							/* get all properties (EMPTY) */
2871							req_props = NULL;
2872						}
2873					}
2874				}
2875
2876				xmlFreeDoc(xml);
2877			} else {
2878				con->http_status = 400;
2879				return HANDLER_FINISHED;
2880			}
2881		}
2882#endif
2883
2884		con->http_status = 207;
2885
2886		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
2887
2888		buffer *b = buffer_init();
2889
2890		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
2891		buffer_append_string_len(b,CONST_STR_LEN("<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\" "));
2892
2893	#if 0
2894		//- Key
2895		buffer_append_string_len(b, CONST_STR_LEN(" key=\""));
2896		char mac[20]="\0";
2897		get_mac_address("eth0", &mac);
2898		char* base64_key = ldb_base64_encode(mac, strlen(mac));
2899		buffer_append_string(b, base64_key);
2900		free(base64_key);
2901
2902		//- Auth
2903		buffer_append_string_len(b, CONST_STR_LEN("\" auth=\""));
2904		char auth_buf[100]="\0";
2905		if(con->smb_info)
2906			sprintf(auth_buf, "%s:%s", con->smb_info->username->ptr, con->smb_info->password->ptr);
2907		char* base64_auth = ldb_base64_encode(auth_buf, strlen(auth_buf));
2908		buffer_append_string(b, base64_auth);
2909		free(base64_auth);
2910
2911		buffer_append_string_len(b, CONST_STR_LEN("\""));
2912	#endif
2913
2914		//- Read Only
2915		buffer_append_string_len(b, CONST_STR_LEN(" readonly=\"0"));
2916
2917		//- Router user name
2918		buffer_append_string_len(b, CONST_STR_LEN("\" ruser=\""));
2919		data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
2920		if(ds!=NULL){
2921			smb_info_t *c;
2922			for (c = srv->smb_srv_info_list; c; c = c->next) {
2923
2924				if( buffer_is_equal(c->user_agent, ds->value) &&
2925				    buffer_is_equal(c->src_ip, con->dst_addr_buf) &&
2926				    buffer_is_empty(c->server) ){
2927					buffer_append_string(b, c->username->ptr);
2928
2929					break;
2930				}
2931
2932			}
2933		}
2934
2935		//- Query Type
2936		buffer_append_string_len(b, CONST_STR_LEN("\" qtype=\""));
2937		char qtype[2]="\0";
2938		sprintf(qtype, "%d", con->smb_info->qflag);
2939		buffer_append_string(b, qtype);
2940
2941	#if EMBEDDED_EANBLE
2942		//- Computer Name
2943		#ifndef APP_IPKG
2944		buffer_append_string_len(b, CONST_STR_LEN("\" computername=\""));
2945		buffer_append_string(b, nvram_get_computer_name());
2946		#else
2947		char *computer_name = nvram_get_computer_name();
2948		buffer_append_string_len(b, CONST_STR_LEN("\" computername=\""));
2949        buffer_append_string(b, computer_name);
2950        //buffer_append_string(b, nvram_get_computer_name());
2951        free(computer_name);
2952		#endif
2953	#else
2954		//- Computer Name
2955		buffer_append_string_len(b, CONST_STR_LEN("\" computername=\"WebDAV"));
2956	#endif
2957
2958		buffer_append_string_len(b, CONST_STR_LEN("\" isusb=\"0"));
2959
2960		buffer_append_string_len(b,CONST_STR_LEN("\">\n"));
2961
2962		/* allprop */
2963		prop_200 = buffer_init();
2964		prop_404 = buffer_init();
2965
2966		switch(depth) {
2967		case 0:
2968			/* Depth: 0 */
2969			switch(con->smb_info->qflag) {
2970			case SMB_FILE_QUERY:
2971				smbdav_get_props(srv, con, p, &con->url, req_props, prop_200, prop_404);
2972				break;
2973			case SMB_SHARE_QUERY:
2974			case SMB_HOST_QUERY:
2975				smbdav_get_share_props(srv, con, p, &con->url, NULL, NULL, 0, 1, req_props, prop_200, prop_404);
2976				break;
2977			}
2978			smbdav_propfind_prepare_response_bulk(srv, con, p, b, &(con->physical), prop_200, prop_404);
2979
2980			break;
2981		case 1:
2982			switch(con->smb_info->qflag) {
2983			case SMB_FILE_QUERY:
2984			{
2985				if (-1 != (dir = smbc_wrapper_opendir(con, con->url.path->ptr))) {
2986					struct smbc_dirent *de;
2987					physical d;
2988
2989					physical *dst = &(con->url);
2990
2991					if(!buffer_is_empty(con->match_smb_ip)){
2992						int index = strstr(dst->rel_path->ptr, con->match_smb_ip->ptr) - dst->rel_path->ptr;
2993						if( index==1 ){
2994							char buff[4096];
2995							char* tmp = replace_str(dst->rel_path->ptr,
2996												    con->match_smb_ip->ptr,
2997												    con->replace_smb_name->ptr,
2998												    (char *)&buff[0]);
2999
3000							buffer_copy_string(dst->rel_path, tmp);
3001						}
3002					}
3003
3004					d.path = buffer_init();
3005					d.rel_path = buffer_init();
3006
3007					while(NULL != (de = smbc_wrapper_readdir(con, dir))) {
3008						if( (de->name[0] == '.' && de->name[1] == '.' && de->name[2] == '\0') ){
3009							continue;
3010							//- ignore the parent dir
3011						}
3012
3013						if ( de->name[0] == '.' ) {
3014							continue;
3015							//- ignore the hidden file
3016						}
3017
3018						buffer* de_name = buffer_init();
3019						buffer_copy_string(de_name, de->name);
3020
3021						buffer_copy_buffer(d.path, dst->path);
3022						buffer_append_slash(d.path);
3023
3024						buffer_copy_buffer(d.rel_path, dst->rel_path);
3025						buffer_append_slash(d.rel_path);
3026
3027						if (de->name[0] == '.' && de->name[1] == '\0') {
3028							/* don't append the . */
3029						} else {
3030							buffer_append_string_buffer(d.path, de_name);
3031							buffer_append_string_buffer(d.rel_path, de_name);
3032						}
3033
3034						buffer_reset(prop_200);
3035						buffer_reset(prop_404);
3036
3037						//Cdbg(DBE,"SMB_FILE_QUERY: de->name %s, d.path %s", de_name->ptr, d.path->ptr);
3038
3039						buffer_free(de_name);
3040
3041						smbdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404);
3042						smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
3043
3044					}
3045					smbc_wrapper_closedir(con,dir);
3046					buffer_free(d.path);
3047					buffer_free(d.rel_path);
3048				}
3049				else{
3050					smbc_wrapper_response_401(srv, con);
3051				}
3052
3053				break;
3054			}
3055
3056			case SMB_SHARE_QUERY:
3057			{
3058				if (-1 != (dir = smbc_wrapper_opensharedir(con, con->url.path->ptr))) {
3059					struct smbc_dirent *de;
3060					physical d;
3061					physical *dst = &(con->physical);
3062
3063					d.path = buffer_init();
3064					d.rel_path = buffer_init();
3065
3066					while(NULL != (de = smbc_wrapper_readdir(con, dir))) {
3067						if( (de->name[0] == '.' && de->name[1] == '.' && de->name[2] == '\0')/* ||
3068							( strstr(de->name, "$") ) */ ){
3069							continue;
3070							/* ignore the parent dir */
3071						}
3072
3073						buffer* de_name = buffer_init();
3074						//buffer_copy_string(de_name, "");
3075						//buffer_append_string_encoded(de_name, de->name, strlen(de->name), ENCODING_REL_URI);
3076						buffer_copy_string(de_name, de->name);
3077
3078
3079						buffer_copy_buffer(d.path, dst->path);
3080						buffer_append_slash(d.path);
3081
3082						buffer_copy_buffer(d.rel_path, dst->rel_path);
3083						buffer_append_slash(d.rel_path);
3084
3085						if( (de->name[0] == '.' && de->name[1] == '\0') ||
3086 						    strstr(de->name, "$") ){
3087							//- don't append the .
3088							//continue;
3089						} else {
3090							//buffer_append_string(d.path, de->name);
3091							//buffer_append_string(d.rel_path, de->name);
3092
3093							buffer_append_string_buffer(d.path, de_name);
3094							buffer_append_string_buffer(d.rel_path, de_name);
3095						}
3096
3097						//Cdbg(DBE,"SMB_SHARE_QUERY: de->name %s, d.path %s", de_name->ptr, d.path->ptr);
3098
3099						buffer_free(de_name);
3100
3101						buffer_reset(prop_200);
3102						buffer_reset(prop_404);
3103
3104						smbdav_get_share_props(srv, con, p, &d, NULL, NULL, 0, 1, req_props, prop_200, prop_404);
3105						smbdav_propfind_prepare_response_bulk(srv, con, p, b, &d, prop_200, prop_404);
3106					}
3107
3108					smbc_wrapper_closedir(con, dir);
3109					buffer_free(d.path);
3110					buffer_free(d.rel_path);
3111				}
3112				else{
3113					smbc_wrapper_response_401(srv, con);
3114				}
3115
3116				break;
3117			}
3118
3119			default:
3120			case SMB_HOST_QUERY:
3121			{
3122				smbc_list_host(srv, con, req_props, p, b, prop_200, prop_404);
3123				break;
3124			}
3125
3126			}
3127			break;
3128		default:
3129			break;
3130		}
3131
3132		if (req_props) {
3133			size_t i;
3134			for (i = 0; i < req_props->used; i++) {
3135				free(req_props->ptr[i]->ns);
3136				free(req_props->ptr[i]->prop);
3137				free(req_props->ptr[i]);
3138			}
3139			free(req_props->ptr);
3140			free(req_props);
3141		}
3142
3143		buffer_free(prop_200);
3144		buffer_free(prop_404);
3145
3146		buffer_append_string_len(b,CONST_STR_LEN("</D:multistatus>\n"));
3147
3148		if (p->conf.log_xml) {
3149			log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
3150		}
3151
3152		chunkqueue_append_buffer(con->write_queue, b);
3153		buffer_free(b);
3154
3155		con->file_finished = 1;
3156		return HANDLER_FINISHED;
3157
3158	case HTTP_METHOD_OAUTH:{
3159		Cdbg(1, "HTTP_METHOD_OAUTH............");
3160#if EMBEDDED_EANBLE
3161		if(!con->srv_socket->is_ssl){
3162			con->http_status = 403;
3163			return HANDLER_FINISHED;
3164		}
3165#endif
3166#if 0
3167		if ((ds = HEADER(con, "Cookie")) != NULL ){
3168			Cdbg(1, "sssssssssssssssssssssssssHTTP_METHOD_OAUTH............%s", ds->value->ptr);
3169			con->http_status = 403;
3170			return HANDLER_FINISHED;
3171		}
3172#endif
3173		char *auth_username = NULL;
3174		char *auth_password = NULL;
3175		if( smbc_parser_basic_authentication(srv, con, &auth_username, &auth_password) != 1 ){
3176			con->http_status = 401;
3177			return HANDLER_FINISHED;
3178		}
3179
3180		// Expected Cookie Format:
3181		//   <name>=crypt:<hash>:<data>
3182		//
3183		//   payload = base64(username + ":" + password)
3184		//   data    = hex( encrypt(MD5(timesegment + key), payload) )
3185		//	hash	 = hex(MD5(key + timesegment + data))
3186
3187
3188		//uint8_t hash[MD5_LEN];
3189		buffer* key = buffer_init_string("shared-secret");
3190		time_t now = time(NULL);
3191		now = now - (now%5);
3192		char timesegment[256] = "\0";
3193		sprintf(timesegment, "%lu", now);
3194
3195		//- payload
3196		buffer* auth = buffer_init_string(auth_username);
3197		buffer_append_string(auth, ":");
3198		buffer_append_string(auth, auth_password);
3199		char* payload = ldb_base64_encode(auth->ptr, strlen(auth->ptr));
3200
3201		//- data
3202		buffer *buf_data = buffer_init();
3203		char* result;
3204		md5String(key->ptr, timesegment, &result);
3205		buffer_copy_string(buf_data, result);
3206		handle_encrypt(buf_data, payload, strlen(payload));
3207
3208		buffer *buf_hex_data = buffer_init();
3209		buffer_copy_string_hex(buf_hex_data, buf_data->ptr, strlen(buf_data->ptr));
3210		Cdbg(1, "buf_hex_data=%s", buf_hex_data->ptr);
3211
3212		//- hash
3213		buffer *buf_hash = buffer_init();
3214		buffer *temp = buffer_init_string(key->ptr);
3215		buffer_append_string(temp, timesegment);
3216		buffer_append_string_buffer(temp, buf_data);
3217		md5String(temp->ptr, NULL, &result);
3218		buffer_copy_string(buf_hash, result);
3219
3220		buffer *buf_hex_hash = buffer_init();
3221		buffer_copy_string_hex(buf_hex_hash, buf_hash->ptr, strlen(buf_hash->ptr));
3222		buffer_free(buf_hash);
3223		Cdbg(1, "buf_hex_hash=%s", buf_hex_hash->ptr);
3224
3225		////////////////////////////////////////////////////////
3226
3227		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text; charset=\"utf-8\""));
3228
3229		b = buffer_init();
3230
3231		buffer_append_string(b, "crypt:");
3232		buffer_append_string_buffer(b, buf_hex_hash);
3233		buffer_append_string(b, ":");
3234		buffer_append_string_buffer(b, buf_hex_data);
3235
3236		Cdbg(1, "b=%s", b->ptr);
3237
3238		chunkqueue_append_buffer(con->write_queue, b);
3239
3240		buffer_free(b);
3241		buffer_free(auth);
3242		buffer_free(key);
3243		buffer_free(buf_data);
3244
3245		con->http_status = 200;
3246		con->file_finished = 1;
3247		return HANDLER_FINISHED;
3248	}
3249
3250	case HTTP_METHOD_MKCOL:
3251		if (p->conf.is_readonly) {
3252			con->http_status = 403;
3253			return HANDLER_FINISHED;
3254		}
3255
3256		if (con->request.content_length != 0) {
3257			/* we don't support MKCOL with a body */
3258			con->http_status = 415;
3259
3260			return HANDLER_FINISHED;
3261		}
3262
3263		/* let's create the directory */
3264		if (-1 == smbc_wrapper_mkdir(con, con->url.path->ptr, WEBDAV_DIR_MODE)) {
3265			switch(errno) {
3266			case EPERM:
3267				con->http_status = 403;
3268				break;
3269			case ENOENT:
3270			case ENOTDIR:
3271				con->http_status = 409;
3272				break;
3273			case EEXIST:
3274			default:
3275				con->http_status = 405; /* not allowed */
3276				break;
3277			}
3278		} else {
3279			log_sys_write(srv, "sbss", "Create folder", con->url.rel_path, "from ip", con->dst_addr_buf->ptr);
3280			con->http_status = 201;
3281			con->file_finished = 1;
3282		}
3283
3284		return HANDLER_FINISHED;
3285
3286
3287	case HTTP_METHOD_DELETE:
3288		if (p->conf.is_readonly) {
3289			con->http_status = 403;
3290			return HANDLER_FINISHED;
3291		}
3292
3293		/* does the client have a lock for this connection ? */
3294		if (!smbdav_has_lock(srv, con, p, con->uri.path)) {
3295			con->http_status = 423;
3296			return HANDLER_FINISHED;
3297		}
3298
3299		/* stat and unlink afterwards */
3300		if (-1 == smbc_wrapper_stat(con, con->url.path->ptr, &st)) {
3301			/* don't about it yet, unlink will fail too */
3302			switch(errno) {
3303			case ENOENT:
3304				 con->http_status = 404;
3305				 break;
3306			default:
3307				 con->http_status = 403;
3308				 break;
3309			}
3310		}
3311		else if (S_ISDIR(st.st_mode)) {
3312			buffer *multi_status_resp = buffer_init();
3313			if (smbdav_delete_dir(srv, con, p, &(con->url), multi_status_resp)) {
3314				#if 0
3315				// we got an error somewhere in between, build a 207
3316				response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
3317
3318				b = chunkqueue_get_append_buffer(con->write_queue);
3319
3320				buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
3321
3322				buffer_append_string_len(b,CONST_STR_LEN("<D:multistatus xmlns:D=\"DAV:\">\n"));
3323
3324				buffer_append_string_buffer(b, multi_status_resp);
3325				Cdbg(DBE, "multi_status_resp = %s", multi_status_resp->ptr);
3326				buffer_append_string_len(b,CONST_STR_LEN("</D:multistatus>\n"));
3327
3328				if (p->conf.log_xml) {
3329					log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
3330				}
3331
3332				con->http_status = 207;
3333				con->file_finished = 1;
3334				#else
3335				con->http_status = 403;
3336				con->file_finished = 1;
3337				#endif
3338			}
3339			else {
3340				// everything went fine, remove the directory
3341				if (-1 == smbc_wrapper_rmdir(con, con->url.path->ptr)) {
3342					switch(errno) {
3343					case EPERM:
3344					case 13:
3345						con->http_status = 403;
3346						break;
3347					case ENOENT:
3348						con->http_status = 404;
3349						break;
3350					default:
3351						con->http_status = 501;
3352						break;
3353					}
3354				} else {
3355					log_sys_write(srv, "sbss", "Delete folder", con->url.rel_path, "from ip", con->dst_addr_buf->ptr);
3356					con->http_status = 204;
3357				}
3358			}
3359
3360			buffer_free(multi_status_resp);
3361		}
3362		else if (-1 == smbc_wrapper_unlink(con, con->url.path->ptr)) {
3363			switch(errno) {
3364			case EPERM:
3365			case 13:
3366				con->http_status = 403;
3367				break;
3368			case ENOENT:
3369				con->http_status = 404;
3370				break;
3371			default:
3372				con->http_status = 501;
3373				break;
3374			}
3375		}
3376		else {
3377			log_sys_write(srv, "sbss", "Delete file", con->url.rel_path, "from ip", con->dst_addr_buf->ptr);
3378			con->http_status = 204;
3379		}
3380		return HANDLER_FINISHED;
3381
3382	case HTTP_METHOD_PUT: {
3383		Cdbg(DBE,"========================================================> mode = %d",con->mode );
3384		int fd;
3385		chunkqueue *cq = con->request_content_queue;
3386		chunk *c;
3387		data_string *ds_range;
3388
3389		if (p->conf.is_readonly) {
3390			con->http_status = 403;
3391			return HANDLER_FINISHED;
3392		}
3393
3394		/* is a exclusive lock set on the source */
3395		if (!smbdav_has_lock(srv, con, p, con->uri.path)) {
3396			con->http_status = 423;
3397			return HANDLER_FINISHED;
3398		}
3399
3400		//- JerryLin add
3401		int autoCreateFolder = 0;
3402		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Auto-CreateFolder"))) {
3403			if (ds->value->used != 2 ||
3404			    (ds->value->ptr[0] != 'F' &&
3405			     ds->value->ptr[0] != 'T') )  {
3406				con->http_status = 400;
3407				return HANDLER_FINISHED;
3408			}
3409			autoCreateFolder = (ds->value->ptr[0] == 'F' ? 0 : 1);
3410		}
3411
3412		if(autoCreateFolder&&con->smb_info){
3413			/*
3414			char* file_path = NULL;
3415			extract_filepath(con->physical.path->ptr, &file_path);
3416			Cdbg(DBE, "aaaaaa file_path=%s", file_path);
3417			if (-1 == smbc_wrapper_mkdir_recursive(con, file_path, WEBDAV_DIR_MODE) ){
3418				con->http_status = 403;
3419			}
3420
3421			free(file_path);
3422			*/
3423
3424			char* at = strstr(con->url.path->ptr, "@");
3425			int prefix_len = at - con->url.path->ptr;
3426			buffer* buffer_prefix_url = buffer_init();
3427			buffer_copy_string_len(buffer_prefix_url,con->url.path->ptr,prefix_len+1);
3428			buffer_append_string_buffer(buffer_prefix_url, con->smb_info->server);
3429			buffer_append_string(buffer_prefix_url, "/");
3430			buffer_append_string_buffer(buffer_prefix_url, con->smb_info->share);
3431			buffer_append_string(buffer_prefix_url, "/");
3432
3433			char* path;
3434			if( extract_filepath(con->smb_info->path->ptr, &path) ){
3435				char* pch;
3436				pch = strtok(path, "/");
3437				while(pch!=NULL){
3438
3439					buffer_append_string(buffer_prefix_url, pch);
3440					buffer_append_string(buffer_prefix_url, "/");
3441					Cdbg(DBE, "buffer_prefix_url=%s", buffer_prefix_url->ptr);
3442					smbc_mkdir(buffer_prefix_url->ptr, WEBDAV_DIR_MODE);
3443
3444					pch = strtok( NULL, "/" );
3445				}
3446				free(path);
3447			}
3448
3449			buffer_free(buffer_prefix_url);
3450		}
3451		////////////////////////////////
3452
3453		assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
3454
3455		/* RFC2616 Section 9.6 PUT requires us to send 501 on all Content-* we don't support
3456		 * - most important Content-Range
3457		 *
3458		 *
3459		 * Example: Content-Range: bytes 100-1037/1038 */
3460
3461		if (NULL != (ds_range = (data_string *)array_get_element(con->request.headers, "Content-Range"))) {
3462			const char *num = ds_range->value->ptr;
3463			off_t offset;
3464			char *err = NULL;
3465			Cdbg(DBE,"Content-Range =%s",num);
3466
3467			if (0 != strncmp(num, "bytes ", 6)) {
3468				con->http_status = 501; /* not implemented */
3469
3470				return HANDLER_FINISHED;
3471			}
3472
3473			/* we only support <num>- ... */
3474			num += 6;
3475
3476			/* skip WS */
3477			while (*num == ' ' || *num == '\t') num++;
3478
3479			if (*num == '\0') {
3480				con->http_status = 501; /* not implemented */
3481				return HANDLER_FINISHED;
3482			}
3483
3484			offset = strtoll(num, &err, 10);
3485
3486			if (*err != '-' || offset < 0) {
3487				con->http_status = 501; /* not implemented */
3488				return HANDLER_FINISHED;
3489			}
3490
3491			//- JerryLin modify if offset is zero, we create a new file.
3492			if(offset==0){
3493				/* if the file doesn't exist, create it */
3494				fd = smbc_wrapper_open(con, con->url.path->ptr, O_WRONLY|O_TRUNC, 0);
3495				if (fd<0 || (void*)fd==NULL ) {
3496					if (errno == ENOENT){
3497						fd = smbc_wrapper_create(con, con->url.path->ptr,  FILE_READ_DATA | FILE_WRITE_DATA,0);
3498						if(fd <0 || (void*)fd==NULL ){
3499							/* we can't open the file */
3500							con->http_status = 403;
3501							return HANDLER_FINISHED;
3502					   }
3503					}
3504					else if (errno == EPERM||errno == 13){
3505						con->http_status = 403;
3506						return HANDLER_FINISHED;
3507					}
3508					else {
3509						con->http_status = 201; /* created */
3510					}
3511				}
3512				else {
3513					con->http_status = 201;
3514				}
3515			}
3516			else{
3517				if (0> (fd = smbc_wrapper_open(con,con->url.path->ptr, O_WRONLY| O_APPEND, 0) )) {
3518
3519					switch (errno) {
3520					case ENOENT:
3521						con->http_status = 404; /* not found */
3522						break;
3523					default:
3524						con->http_status = 403; /* not found */
3525						break;
3526					}
3527
3528					if (errno == ENOENT){
3529						fd = smbc_wrapper_create(con, con->url.path->ptr,  FILE_READ_DATA | FILE_WRITE_DATA,0);
3530						if(fd <0 || (void*)fd==NULL ){
3531
3532							/* we can't open the file */
3533							con->http_status = 403;
3534							Cdbg(DBE,"we can't open the file 403");
3535							return HANDLER_FINISHED;
3536					   }
3537					}
3538					else if (errno == EPERM||errno == 13){
3539						con->http_status = 403;
3540						return HANDLER_FINISHED;
3541					}
3542					else {
3543						con->http_status = 201; /* created */
3544					}
3545				}
3546			}
3547
3548			if (-1 == smbc_wrapper_lseek(con, fd, offset, SEEK_SET)) {
3549				con->http_status = 501; /* not implemented */
3550				smbc_wrapper_close(con,fd);
3551				return HANDLER_FINISHED;
3552			}
3553
3554			con->http_status = 200; /* modified */
3555		}
3556		else {
3557
3558		   	Cdbg(DBE,"ds range= NUL, url =%s",con->url.path->ptr);
3559			/* take what we have in the request-body and write it to a file */
3560
3561			/* if the file doesn't exist, create it */
3562		   	Cdbg(DBE,"ready to smbc open, %s", con->url.path->ptr);
3563			fd = smbc_wrapper_open(con, con->url.path->ptr, O_WRONLY|O_TRUNC, /*WEBDAV_FILE_MODE*/0);
3564			if (fd<0 || (void*)fd==NULL ) {
3565				Cdbg(DBE,"open failed errno=%d",errno);
3566				if (errno == ENOENT){
3567					fd = smbc_wrapper_create(con, con->url.path->ptr,  FILE_READ_DATA | FILE_WRITE_DATA,0);
3568					if(fd <0 || (void*)fd==NULL ){
3569
3570						/* we can't open the file */
3571						con->http_status = 403;
3572						Cdbg(DBE,"we can't open the file 403");
3573						return HANDLER_FINISHED;
3574				   }
3575				}
3576				else if (errno == EPERM||errno == 13){
3577					con->http_status = 403;
3578					return HANDLER_FINISHED;
3579				}
3580				else {
3581					con->http_status = 201; /* created */
3582				}
3583			}
3584			else {
3585				con->http_status = 201;
3586			}
3587		}
3588
3589		con->file_finished = 1;
3590		Cdbg(DBE,"file finished=%d cq=%p",con->file_finished,cq);
3591
3592		for (c = cq->first; c; c = cq->first) {
3593			int r = 0;
3594
3595			/* copy all chunks */
3596			switch(c->type) {
3597			case SMB_CHUNK:
3598				Cdbg(DBE,"SMB_CHUNK: ============================================>");
3599				r=0;
3600				c->offset = con->request.content_length;
3601				cq->bytes_out = con->request.content_length;
3602				Cdbg(1,"offset = %lli, bytes_out=%lli", c->offset, cq->bytes_out);
3603				break;
3604
3605			case FILE_CHUNK:
3606				Cdbg(DBE,"FILE_CHUNK %s", c->file.name->ptr);
3607
3608				if (c->file.mmap.start == MAP_FAILED) {
3609					Cdbg(DBE, "MAP_FAILED");
3610					if (-1 == c->file.fd &&  /* open the file if not already open */
3611					    -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
3612						log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
3613
3614						return HANDLER_ERROR;
3615					}
3616
3617					if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
3618						log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
3619								strerror(errno), c->file.name,  c->file.fd);
3620						close(c->file.fd);
3621						c->file.fd = -1;
3622
3623						return HANDLER_ERROR;
3624					}
3625
3626					c->file.mmap.length = c->file.length;
3627
3628					close(c->file.fd);
3629					c->file.fd = -1;
3630
3631					/* chunk_reset() or chunk_free() will cleanup for us */
3632				}
3633
3634				Cdbg(DBE, "c->file.mmap.start = %d, c->offset = %d, c->file.length = %d", c->file.mmap.start, c->offset, c->file.length );
3635				Cdbg(DBE, "smbc_wrapper_write %d, %d", c->file.mmap.start + c->offset, c->file.length - c->offset - 1 );
3636				size_t wrlen2 = c->file.length - (size_t)c->offset;
3637//				if((r=  smbc_wrapper_write(con, fd, c->mem->ptr + c->offset,c->mem->used - c->offset - 1, 0))<0 ){
3638				if((r=  smbc_wrapper_write(con, fd, c->file.mmap.start + c->offset, wrlen2, 0))<0 ){
3639				//if((r= smbc_wrapper_write(con, fd, c->file.mmap.start + c->offset, c->file.length - c->offset, 0))<0 ){
3640				//if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
3641					switch(errno) {
3642					case ENOSPC:
3643						con->http_status = 507;
3644						break;
3645					default:
3646
3647						con->http_status = 403;
3648						break;
3649					}
3650				}
3651
3652				break;
3653			case MEM_CHUNK:
3654				Cdbg(DBE,"MEM_CHUNK:");
3655				//Cdbg(DBE,"fd =%p, mem=%p , content=%s",fd, c->mem->ptr + c->offset, c->mem->ptr + c->offset);
3656
3657				size_t wrlen = c->mem->used - (size_t)c->offset - 1;
3658//				if((r=  smbc_wrapper_write(con, fd, c->mem->ptr + c->offset,c->mem->used - c->offset - 1, 0))<0 ){
3659				if((r=  smbc_wrapper_write(con, fd, c->mem->ptr + c->offset, wrlen, 0))<0 ){
3660			//	if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
3661					switch(errno) {
3662					case ENOSPC:
3663						con->http_status = 507;
3664
3665						break;
3666					default:
3667						con->http_status = 403;
3668						break;
3669					}
3670				}
3671				break;
3672			case UNUSED_CHUNK:
3673				Cdbg(DBE,"UNUSED CHUNK");
3674				break;
3675			}
3676
3677			Cdbg(DBE,"r =%d", r);
3678			Cdbg(DBE," c->offset= %lli", c->offset);
3679			Cdbg(DBE," c->bytes_out = %lli", cq->bytes_out);
3680			if (r > 0) {
3681				c->offset += r;
3682				cq->bytes_out += r;
3683			} else {
3684			   Cdbg(DBE,"r <0");
3685				break;
3686			}
3687			   Cdbg(DBE," c->offset= %lli", c->offset);
3688			   Cdbg(DBE," c->bytes_out = %lli", cq->bytes_out);
3689			chunkqueue_remove_finished_chunks(cq);
3690		}
3691//		close(fd);
3692		Cdbg(DBE,"close smb file https =%d",con->http_status);
3693		if(fd>0) smbc_wrapper_close(con, fd);
3694		Cdbg(DBE,"METHOD_PUT ends");
3695
3696		//log_sys_write(srv, "sbss", "Upload", con->url.rel_path, "from ip", con->dst_addr_buf->ptr);
3697
3698		return HANDLER_FINISHED;
3699	}
3700	case HTTP_METHOD_MOVE:
3701	case HTTP_METHOD_COPY: {
3702		buffer *destination = NULL;
3703		char *sep, *sep2, *start;
3704		int overwrite = 1;
3705
3706		if (p->conf.is_readonly) {
3707			con->http_status = 403;
3708			return HANDLER_FINISHED;
3709		}
3710
3711		/* is a exclusive lock set on the source */
3712		if (con->request.http_method == HTTP_METHOD_MOVE) {
3713			if (!smbdav_has_lock(srv, con, p, con->uri.path)) {
3714				con->http_status = 423;
3715				return HANDLER_FINISHED;
3716			}
3717		}
3718
3719		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) {
3720			destination = ds->value;
3721		} else {
3722			con->http_status = 400;
3723			return HANDLER_FINISHED;
3724		}
3725
3726		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Overwrite"))) {
3727			if (ds->value->used != 2 ||
3728			    (ds->value->ptr[0] != 'F' &&
3729			     ds->value->ptr[0] != 'T') )  {
3730				con->http_status = 400;
3731				return HANDLER_FINISHED;
3732			}
3733
3734			overwrite = (ds->value->ptr[0] == 'F' ? 0 : 1);
3735		}
3736		/* let's parse the Destination
3737		 *
3738		 * http://127.0.0.1:1025/dav/litmus/copydest
3739		 *
3740		 * - host has to be the same as the Host: header we got
3741		 * - we have to stay inside the document root
3742		 * - the query string is thrown away
3743		 *  */
3744
3745		buffer_reset(p->uri.scheme);
3746		buffer_reset(p->uri.path_raw);
3747		buffer_reset(p->uri.authority);
3748
3749		start = destination->ptr;
3750
3751		if (NULL == (sep = strstr(start, "://"))) {
3752			con->http_status = 400;
3753			return HANDLER_FINISHED;
3754		}
3755		buffer_copy_string_len(p->uri.scheme, start, sep - start);
3756
3757		start = sep + 3;
3758
3759		if (NULL == (sep = strchr(start, '/'))) {
3760			con->http_status = 400;
3761			return HANDLER_FINISHED;
3762		}
3763		if (NULL != (sep2 = memchr(start, '@', sep - start))) {
3764			/* skip login information */
3765			start = sep2 + 1;
3766		}
3767		buffer_copy_string_len(p->uri.authority, start, sep - start);
3768
3769		start = sep + 1;
3770
3771		if (NULL == (sep = strchr(start, '?'))) {
3772			/* no query string, good */
3773			buffer_copy_string(p->uri.path_raw, start);
3774		} else {
3775			buffer_copy_string_len(p->uri.path_raw, start, sep - start);
3776		}
3777
3778		if (!buffer_is_equal(p->uri.authority, con->uri.authority)) {
3779			/* not the same host */
3780			con->http_status = 502;
3781			return HANDLER_FINISHED;
3782		}
3783
3784		buffer_copy_buffer(p->tmp_buf, p->uri.path_raw);
3785		buffer_urldecode_path(p->tmp_buf);
3786		buffer_path_simplify(p->uri.path, p->tmp_buf);
3787
3788		//- 20121115 JerryLin add for router sync.
3789		if(con->share_link_shortpath->used){
3790			char* a;
3791			if (NULL != ( a = strstr(p->uri.path->ptr, con->share_link_shortpath->ptr))){
3792				char buff[4096];
3793				replace_str( a,
3794					         con->share_link_shortpath->ptr,
3795					         con->share_link_realpath->ptr,
3796					         buff );
3797				buffer_copy_string( p->uri.path, buff );
3798			}
3799			else{
3800				con->http_status = 502;
3801				return HANDLER_FINISHED;
3802			}
3803		}
3804
3805		//- check if usbdisk path
3806#if EMBEDDED_EANBLE
3807		char* a = nvram_get_productid();
3808		char usbdisk_path[100]="\0";
3809		char usbdisk_rel_path[100]="/tmp/mnt";
3810		strcpy(usbdisk_path, "/");
3811		strcat(usbdisk_path, a);
3812		#ifdef APP_IPKG
3813		free(a);
3814		#endif
3815#else
3816		char usbdisk_path[10]="/usbdisk";
3817		char usbdisk_rel_path[100]="/mnt";
3818#endif
3819
3820		//int index = strstr(p->uri.path->ptr, usbdisk_path) - p->uri.path->ptr;
3821		//Cdbg(1,"1111, %s, %s, index = %d", p->uri.path->ptr, usbdisk_path, index);
3822
3823		//if(index==0){
3824		if(prefix_is(p->uri.path->ptr, usbdisk_path)==1){
3825
3826			buffer_copy_buffer(p->physical.rel_path, p->uri.path);
3827
3828			if (con->conf.force_lowercase_filenames) {
3829				buffer_to_lower(p->physical.rel_path);
3830			}
3831
3832			buffer_copy_buffer(p->physical.path, p->physical.rel_path);
3833
3834			char buff[2048]="\0";
3835			char* tmp = replace_str(p->physical.rel_path->ptr,
3836									usbdisk_path,
3837									usbdisk_rel_path,
3838									(char *)&buff[0]);
3839			buffer_copy_string(p->physical.rel_path, tmp);
3840		}
3841		else{
3842			/* we now have a URI which is clean. transform it into a physical path */
3843			buffer_copy_buffer(p->physical.doc_root, con->physical.doc_root);
3844			buffer_copy_buffer(p->physical.rel_path, p->uri.path);
3845
3846			if (con->conf.force_lowercase_filenames) {
3847				buffer_to_lower(p->physical.rel_path);
3848			}
3849
3850			buffer_copy_buffer(p->physical.path, p->physical.doc_root);
3851			buffer_append_slash(p->physical.path);
3852			buffer_copy_buffer(p->physical.basedir, p->physical.path);
3853
3854			/* don't add a second / */
3855			if (p->physical.rel_path->ptr[0] == '/') {
3856				//- Jerry add
3857				buffer_append_string(p->physical.path, con->smb_info->username->ptr);
3858				buffer_append_string(p->physical.path,":");
3859				buffer_append_string(p->physical.path, con->smb_info->password->ptr);
3860				buffer_append_string(p->physical.path,"@");
3861
3862				char* tmp = p->physical.rel_path->ptr + 1;
3863				int len = p->physical.rel_path->used - 2;
3864				//buffer_append_string_encoded(p->physical.path, tmp, len, ENCODING_REL_URI);
3865				buffer_append_string(p->physical.path, tmp);
3866			} else {
3867				buffer_append_string_buffer(p->physical.path, p->physical.rel_path);
3868			}
3869		}
3870
3871		//- con->url.path is url-decode string.
3872		//- p->uri.path is url-decode string.
3873		//- p->physical.rel_path is url-decode string.
3874		//- p->physical.path is url-decode string.
3875
3876		/* let's see if the source is a directory
3877		 * if yes, we fail with 501 */
3878		if (-1 == smbc_wrapper_stat(con, con->url.path->ptr, &st)) {
3879			/* don't about it yet, unlink will fail too */
3880			switch(errno) {
3881			case ENOENT:
3882				 con->http_status = 404;
3883				 break;
3884			default:{
3885				 con->http_status = 403;
3886				 break;
3887				}
3888			}
3889		}
3890		else if (S_ISDIR(st.st_mode)) {
3891			int r;
3892			/* src is a directory */
3893			r = smbc_wrapper_stat(con, p->physical.path->ptr, &st);
3894			if (r == -1) {
3895				if(in_the_same_folder(con->url.path, p->physical.path)) {
3896					if( smbc_rename(con->url.path->ptr, p->physical.path->ptr) ) {
3897						con->http_status = 403;
3898					} else {
3899						con->http_status = 201; //Created
3900						log_sys_write(srv, "sbsbss", "Move", con->url.rel_path, "to", p->physical.rel_path ,"from ip", con->dst_addr_buf->ptr);
3901					}
3902					con->file_finished = 1;
3903					return HANDLER_FINISHED;
3904				} else if (-1 == smbdav_create_dir(srv, con, &(p->physical))) {
3905					con->http_status = 403;
3906					return HANDLER_FINISHED;
3907				}
3908			}
3909			else if (!S_ISDIR(st.st_mode)) {
3910				if (overwrite == 0) {
3911					/* copying into a non-dir ? */
3912					con->http_status = 409;
3913					return HANDLER_FINISHED;
3914				} else {
3915					smbc_wrapper_unlink(con, con->url.path->ptr);
3916					if (-1 == smbdav_create_dir(srv, con, &(con->url))) {
3917						con->http_status = 403;
3918						return HANDLER_FINISHED;
3919					}
3920				}
3921			}
3922			else if (S_ISDIR(st.st_mode)) {
3923				//- dst folder is exist.
3924				if (overwrite == 0) {
3925					/* copying into a non-dir ? */
3926					con->http_status = 412;
3927					return HANDLER_FINISHED;
3928				}
3929			}
3930
3931			/* copy the content of src to dest */
3932			if (0 != (r = smbdav_copy_dir(srv, con, p, &(con->url), &(p->physical), overwrite))) {
3933				con->http_status = r;
3934				return HANDLER_FINISHED;
3935			}
3936
3937			if (con->request.http_method == HTTP_METHOD_MOVE) {
3938				b = buffer_init();
3939				smbdav_delete_dir(srv, con, p, &(con->url), b); /* content */
3940				buffer_free(b);
3941
3942				smbc_wrapper_rmdir(con, con->url.path->ptr);
3943
3944				log_sys_write(srv, "sbsbss", "Move", con->url.rel_path, "to", p->physical.rel_path ,"from ip", con->dst_addr_buf->ptr);
3945			}
3946			con->http_status = 201;
3947			con->file_finished = 1;
3948		}
3949		else {
3950			/* it is just a file, good */
3951			int r;
3952
3953			/* does the client have a lock for this connection ? */
3954			if (!smbdav_has_lock(srv, con, p, p->uri.path)) {
3955				con->http_status = 423;
3956				return HANDLER_FINISHED;
3957			}
3958
3959			/* destination exists */
3960			if (0 == (r = smbc_wrapper_stat(con, con->url.path->ptr, &st))) {
3961				if (S_ISDIR(st.st_mode)) {
3962					if (overwrite == 0) {
3963						/* copying into a non-dir ? */
3964						con->http_status = 409;
3965						return HANDLER_FINISHED;
3966					}
3967
3968					/* file to dir/
3969					 * append basename to physical path */
3970					if (NULL != (sep = strrchr(con->physical.path->ptr, '/'))) {
3971						buffer_append_string(p->physical.path, sep);
3972						r = smbc_wrapper_stat(con, con->url.path->ptr, &st);
3973					}
3974				}
3975			}
3976
3977			if (-1 == r) {
3978				con->http_status = 201; /* we will create a new one */
3979				con->file_finished = 1;
3980
3981				switch(errno) {
3982				case ENOTDIR:
3983					con->http_status = 409;
3984					return HANDLER_FINISHED;
3985				}
3986			}
3987			else {
3988				con->http_status = 204; /* resource already existed */
3989			}
3990
3991			if (con->request.http_method == HTTP_METHOD_MOVE) {
3992				/* try a rename */
3993				Cdbg(DBE,"smbc_rename it is just a file, good %s, %s", con->url.path->ptr, p->physical.path->ptr);
3994
3995				if (0 == smbc_rename(con->url.path->ptr, p->physical.path->ptr)) {
3996#ifdef USE_PROPPATCH
3997					sqlite3_stmt *stmt;
3998
3999					stmt = p->conf.stmt_delete_uri;
4000					if (stmt) {
4001
4002						sqlite3_reset(stmt);
4003
4004						/* bind the values to the insert */
4005						sqlite3_bind_text(stmt, 1,
4006								  con->uri.path->ptr,
4007								  con->uri.path->used - 1,
4008								  SQLITE_TRANSIENT);
4009
4010						if (SQLITE_DONE != sqlite3_step(stmt)) {
4011							log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move(delete old) failed:", sqlite3_errmsg(p->conf.sql));
4012						}
4013					}
4014
4015					stmt = p->conf.stmt_move_uri;
4016					if (stmt) {
4017
4018						sqlite3_reset(stmt);
4019
4020						/* bind the values to the insert */
4021						sqlite3_bind_text(stmt, 1,
4022								  p->uri.path->ptr,
4023								  p->uri.path->used - 1,
4024								  SQLITE_TRANSIENT);
4025
4026						sqlite3_bind_text(stmt, 2,
4027								  con->uri.path->ptr,
4028								  con->uri.path->used - 1,
4029								  SQLITE_TRANSIENT);
4030
4031						if (SQLITE_DONE != sqlite3_step(stmt)) {
4032							log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql));
4033						}
4034					}
4035#endif
4036					log_sys_write(srv, "sbsbss", "Move", con->url.rel_path, "to", p->physical.rel_path ,"from ip", con->dst_addr_buf->ptr);
4037
4038					return HANDLER_FINISHED;
4039				}
4040
4041				/* rename failed, fall back to COPY + DELETE */
4042			}
4043
4044			if (0 != (r = smbdav_copy_file(srv, con, p, &(con->url), &(p->physical), overwrite))) {
4045				con->http_status = r;
4046				return HANDLER_FINISHED;
4047			}
4048
4049			if (con->request.http_method == HTTP_METHOD_MOVE) {
4050				b = buffer_init();
4051				smbdav_delete_file(srv, con, p, &(con->url), b);
4052				buffer_free(b);
4053				log_sys_write(srv, "sbsbss", "Move", con->url.rel_path, "to", p->physical.rel_path ,"from ip", con->dst_addr_buf->ptr);
4054			}
4055		}
4056
4057		return HANDLER_FINISHED;
4058	}
4059	case HTTP_METHOD_PROPPATCH:
4060		if (p->conf.is_readonly) {
4061			con->http_status = 403;
4062			return HANDLER_FINISHED;
4063		}
4064
4065		if (!smbdav_has_lock(srv, con, p, con->uri.path)) {
4066			con->http_status = 423;
4067			return HANDLER_FINISHED;
4068		}
4069
4070		/* check if destination exists */
4071		if (-1 == smbc_wrapper_stat(con, con->physical.path->ptr, &st)) {
4072			switch(errno) {
4073			case ENOENT:
4074				con->http_status = 404;
4075				break;
4076			}
4077		}
4078
4079#ifdef USE_PROPPATCH
4080		if (con->request.content_length) {
4081			xmlDocPtr xml;
4082
4083			if (1 == smbdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
4084				xmlNode *rootnode = xmlDocGetRootElement(xml);
4085
4086				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "propertyupdate")) {
4087					xmlNode *cmd;
4088					char *err = NULL;
4089					int empty_ns = 0; /* send 400 on a empty namespace attribute */
4090
4091					/* start response */
4092
4093					if (SQLITE_OK != sqlite3_exec(p->conf.sql, "BEGIN TRANSACTION", NULL, NULL, &err)) {
4094						log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
4095						sqlite3_free(err);
4096
4097						goto propmatch_cleanup;
4098					}
4099
4100					/* a UPDATE request, we know 'set' and 'remove' */
4101					for (cmd = rootnode->children; cmd; cmd = cmd->next) {
4102						xmlNode *props;
4103						/* either set or remove */
4104
4105						if ((0 == xmlStrcmp(cmd->name, BAD_CAST "set")) ||
4106						    (0 == xmlStrcmp(cmd->name, BAD_CAST "remove"))) {
4107
4108							sqlite3_stmt *stmt;
4109
4110							stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ?
4111								p->conf.stmt_delete_prop : p->conf.stmt_update_prop;
4112
4113							for (props = cmd->children; props; props = props->next) {
4114								if (0 == xmlStrcmp(props->name, BAD_CAST "prop")) {
4115									xmlNode *prop;
4116									int r;
4117
4118									prop = props->children;
4119
4120									if (prop->ns &&
4121									    (0 == xmlStrcmp(prop->ns->href, BAD_CAST "")) &&
4122									    (0 != xmlStrcmp(prop->ns->prefix, BAD_CAST ""))) {
4123										log_error_write(srv, __FILE__, __LINE__, "ss",
4124												"no name space for:",
4125												prop->name);
4126
4127										empty_ns = 1;
4128										break;
4129									}
4130
4131									sqlite3_reset(stmt);
4132
4133									/* bind the values to the insert */
4134
4135									sqlite3_bind_text(stmt, 1,
4136											  con->uri.path->ptr,
4137											  con->uri.path->used - 1,
4138											  SQLITE_TRANSIENT);
4139									sqlite3_bind_text(stmt, 2,
4140											  (char *)prop->name,
4141											  strlen((char *)prop->name),
4142											  SQLITE_TRANSIENT);
4143									if (prop->ns) {
4144										sqlite3_bind_text(stmt, 3,
4145												  (char *)prop->ns->href,
4146												  strlen((char *)prop->ns->href),
4147												  SQLITE_TRANSIENT);
4148									} else {
4149										sqlite3_bind_text(stmt, 3,
4150												  "",
4151												  0,
4152												  SQLITE_TRANSIENT);
4153									}
4154									if (stmt == p->conf.stmt_update_prop) {
4155										sqlite3_bind_text(stmt, 4,
4156											  (char *)xmlNodeGetContent(prop),
4157											  strlen((char *)xmlNodeGetContent(prop)),
4158											  SQLITE_TRANSIENT);
4159									}
4160
4161									if (SQLITE_DONE != (r = sqlite3_step(stmt))) {
4162										log_error_write(srv, __FILE__, __LINE__, "ss",
4163												"sql-set failed:", sqlite3_errmsg(p->conf.sql));
4164									}
4165								}
4166							}
4167							if (empty_ns) break;
4168						}
4169					}
4170
4171					if (empty_ns) {
4172						if (SQLITE_OK != sqlite3_exec(p->conf.sql, "ROLLBACK", NULL, NULL, &err)) {
4173							log_error_write(srv, __FILE__, __LINE__, "ss", "can't rollback transaction:", err);
4174							sqlite3_free(err);
4175
4176							goto propmatch_cleanup;
4177						}
4178
4179						con->http_status = 400;
4180					} else {
4181						if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) {
4182							log_error_write(srv, __FILE__, __LINE__, "ss", "can't commit transaction:", err);
4183							sqlite3_free(err);
4184
4185							goto propmatch_cleanup;
4186						}
4187						con->http_status = 200;
4188					}
4189					con->file_finished = 1;
4190
4191					return HANDLER_FINISHED;
4192				}
4193
4194propmatch_cleanup:
4195
4196				xmlFreeDoc(xml);
4197			} else {
4198				con->http_status = 400;
4199				return HANDLER_FINISHED;
4200			}
4201		}
4202#endif
4203		con->http_status = 501;
4204		return HANDLER_FINISHED;
4205	case HTTP_METHOD_LOCK:
4206		/**
4207		 * a mac wants to write
4208		 *
4209		 * LOCK /dav/expire.txt HTTP/1.1\r\n
4210		 * User-Agent: WebDAVFS/1.3 (01308000) Darwin/8.1.0 (Power Macintosh)\r\n
4211		 * Accept: * / *\r\n
4212		 * Depth: 0\r\n
4213		 * Timeout: Second-600\r\n
4214		 * Content-Type: text/xml; charset=\"utf-8\"\r\n
4215		 * Content-Length: 229\r\n
4216		 * Connection: keep-alive\r\n
4217		 * Host: 192.168.178.23:1025\r\n
4218		 * \r\n
4219		 * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n
4220		 * <D:lockinfo xmlns:D=\"DAV:\">\n
4221		 *  <D:lockscope><D:exclusive/></D:lockscope>\n
4222		 *  <D:locktype><D:write/></D:locktype>\n
4223		 *  <D:owner>\n
4224		 *   <D:href>http://www.apple.com/smbdav_fs/</D:href>\n
4225		 *  </D:owner>\n
4226		 * </D:lockinfo>\n
4227		 */
4228		depth = 0;
4229		if (depth != 0 && depth != -1) {
4230			con->http_status = 400;
4231			return HANDLER_FINISHED;
4232		}
4233
4234#ifdef USE_LOCKS
4235		if (con->request.content_length) {
4236			xmlDocPtr xml;
4237			buffer *hdr_if = NULL;
4238
4239			if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
4240				hdr_if = ds->value;
4241			}
4242
4243			/* we don't support Depth: Infinity on locks */
4244			if (hdr_if == NULL && depth == -1) {
4245				con->http_status = 409; /* Conflict */
4246				return HANDLER_FINISHED;
4247			}
4248
4249			if (1 == smbdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
4250				xmlNode *rootnode = xmlDocGetRootElement(xml);
4251
4252				assert(rootnode);
4253
4254				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) {
4255					xmlNode *lockinfo;
4256					const xmlChar *lockscope = NULL, *locktype = NULL; /* TODO: compiler says unused: *owner = NULL; */
4257
4258					for (lockinfo = rootnode->children; lockinfo; lockinfo = lockinfo->next) {
4259						if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "lockscope")) {
4260							xmlNode *value;
4261							for (value = lockinfo->children; value; value = value->next) {
4262								if ((0 == xmlStrcmp(value->name, BAD_CAST "exclusive")) ||
4263								    (0 == xmlStrcmp(value->name, BAD_CAST "shared"))) {
4264									lockscope = value->name;
4265								} else {
4266									con->http_status = 400;
4267
4268									xmlFreeDoc(xml);
4269									return HANDLER_FINISHED;
4270								}
4271							}
4272						} else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "locktype")) {
4273							xmlNode *value;
4274							for (value = lockinfo->children; value; value = value->next) {
4275								if ((0 == xmlStrcmp(value->name, BAD_CAST "write"))) {
4276									locktype = value->name;
4277								} else {
4278									con->http_status = 400;
4279
4280									xmlFreeDoc(xml);
4281									return HANDLER_FINISHED;
4282								}
4283							}
4284
4285						} else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) {
4286						}
4287					}
4288
4289					if (lockscope && locktype) {
4290						sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
4291
4292						/* is this resourse already locked ? */
4293
4294						/* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout
4295						 *   FROM locks
4296						 *  WHERE resource = ? */
4297
4298						if (stmt) {
4299
4300							sqlite3_reset(stmt);
4301
4302							sqlite3_bind_text(stmt, 1,
4303									  con->uri.path->ptr,
4304									  con->uri.path->used - 1,
4305									  SQLITE_TRANSIENT);
4306							/*
4307							sqlite3_bind_text(stmt, 1,
4308									  p->uri.path->ptr,
4309									  p->uri.path->used - 1,
4310									  SQLITE_TRANSIENT);
4311							*/
4312							/* it is the PK */
4313							while (SQLITE_ROW == sqlite3_step(stmt)) {
4314								/* we found a lock
4315								 * 1. is it compatible ?
4316								 * 2. is it ours */
4317								char *sql_lockscope = (char *)sqlite3_column_text(stmt, 2);
4318
4319								//exclusive
4320								if (strcmp(sql_lockscope, "exclusive")) {
4321									con->http_status = 423;
4322								} else if (0 == xmlStrcmp(lockscope, BAD_CAST "exclusive")) {
4323									/* resourse is locked with a shared lock
4324									 * client wants exclusive */
4325									con->http_status = 423;
4326								}
4327							}
4328							if (con->http_status == 423) {
4329								xmlFreeDoc(xml);
4330								return HANDLER_FINISHED;
4331							}
4332						}
4333
4334						stmt = p->conf.stmt_create_lock;
4335						if (stmt) {
4336							/* create a lock-token */
4337							char uuid[37] /* 36 + \0 */;
4338
4339							sprintf( uuid, "%d", rand() );
4340							/*
4341							#if EMBEDDED_EANBLE
4342							sprintf( uuid, "%d", rand() );
4343							#else
4344							uuid_t id;
4345							uuid_generate(id);
4346							uuid_unparse(id, uuid);
4347							#endif
4348							*/
4349
4350							buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("opaquelocktoken:"));
4351							buffer_append_string(p->tmp_buf, uuid);
4352
4353							/* "CREATE TABLE locks ("
4354							 * "  locktoken TEXT NOT NULL,"
4355							 * "  resource TEXT NOT NULL,"
4356							 * "  lockscope TEXT NOT NULL,"
4357							 * "  locktype TEXT NOT NULL,"
4358							 * "  owner TEXT NOT NULL,"
4359							 * "  depth INT NOT NULL,"
4360							 */
4361
4362							sqlite3_reset(stmt);
4363
4364							sqlite3_bind_text(stmt, 1,
4365									  CONST_BUF_LEN(p->tmp_buf),
4366									  SQLITE_TRANSIENT);
4367							Cdbg(DBE, "5 p->tmp_buf=%s", p->tmp_buf->ptr);
4368							sqlite3_bind_text(stmt, 2,
4369									  CONST_BUF_LEN(con->uri.path),
4370									  SQLITE_TRANSIENT);
4371							Cdbg(DBE, "6 con->uri.path=%s", con->uri.path->ptr);
4372							sqlite3_bind_text(stmt, 3,
4373									  (const char *)lockscope,
4374									  xmlStrlen(lockscope),
4375									  SQLITE_TRANSIENT);
4376
4377							sqlite3_bind_text(stmt, 4,
4378									  (const char *)locktype,
4379									  xmlStrlen(locktype),
4380									  SQLITE_TRANSIENT);
4381
4382							/* owner */
4383							sqlite3_bind_text(stmt, 5,
4384									  "",
4385									  0,
4386									  SQLITE_TRANSIENT);
4387
4388							/* depth */
4389							sqlite3_bind_int(stmt, 6,
4390									 depth);
4391
4392
4393							if (SQLITE_DONE != sqlite3_step(stmt)) {
4394								log_error_write(srv, __FILE__, __LINE__, "ss",
4395										"create lock:", sqlite3_errmsg(p->conf.sql));
4396							}
4397
4398							/* looks like we survived */
4399							smbdav_lockdiscovery(srv, con, p->tmp_buf, (const char *)lockscope, (const char *)locktype, depth);
4400
4401							con->http_status = 201;
4402							con->file_finished = 1;
4403						}
4404					}
4405				}
4406
4407				xmlFreeDoc(xml);
4408				return HANDLER_FINISHED;
4409			} else {
4410				con->http_status = 400;
4411				return HANDLER_FINISHED;
4412			}
4413		} else {
4414
4415			if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
4416				buffer *locktoken = ds->value;
4417				sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
4418
4419				/* remove the < > around the token */
4420				if (locktoken->used < 6) {
4421					con->http_status = 400;
4422
4423					return HANDLER_FINISHED;
4424				}
4425
4426				buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
4427
4428				sqlite3_reset(stmt);
4429
4430				sqlite3_bind_text(stmt, 1,
4431					  CONST_BUF_LEN(p->tmp_buf),
4432					  SQLITE_TRANSIENT);
4433
4434				if (SQLITE_DONE != sqlite3_step(stmt)) {
4435					log_error_write(srv, __FILE__, __LINE__, "ss",
4436						"refresh lock:", sqlite3_errmsg(p->conf.sql));
4437				}
4438
4439				smbdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0);
4440
4441				con->http_status = 200;
4442				con->file_finished = 1;
4443				return HANDLER_FINISHED;
4444			} else {
4445				/* we need a lock-token to refresh */
4446				con->http_status = 400;
4447
4448				return HANDLER_FINISHED;
4449			}
4450		}
4451		break;
4452#else
4453		con->http_status = 501;
4454		return HANDLER_FINISHED;
4455#endif
4456	case HTTP_METHOD_UNLOCK:
4457#ifdef USE_LOCKS
4458		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Lock-Token"))) {
4459			buffer *locktoken = ds->value;
4460			sqlite3_stmt *stmt = p->conf.stmt_remove_lock;
4461
4462			/* remove the < > around the token */
4463			if (locktoken->used < 4) {
4464				con->http_status = 400;
4465
4466				return HANDLER_FINISHED;
4467			}
4468
4469			/**
4470			 * FIXME:
4471			 *
4472			 * if the resourse is locked:
4473			 * - by us: unlock
4474			 * - by someone else: 401
4475			 * if the resource is not locked:
4476			 * - 412
4477			 *  */
4478
4479			buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
4480
4481			sqlite3_reset(stmt);
4482
4483			sqlite3_bind_text(stmt, 1,
4484				  CONST_BUF_LEN(p->tmp_buf),
4485				  SQLITE_TRANSIENT);
4486
4487			sqlite3_bind_text(stmt, 2,
4488				  CONST_BUF_LEN(con->uri.path),
4489				  SQLITE_TRANSIENT);
4490
4491			if (SQLITE_DONE != sqlite3_step(stmt)) {
4492				log_error_write(srv, __FILE__, __LINE__, "ss",
4493					"remove lock:", sqlite3_errmsg(p->conf.sql));
4494			}
4495
4496			if (0 == sqlite3_changes(p->conf.sql)) {
4497				con->http_status = 401;
4498			} else {
4499				con->http_status = 204;
4500			}
4501			return HANDLER_FINISHED;
4502		} else {
4503			/* we need a lock-token to unlock */
4504			con->http_status = 400;
4505
4506			return HANDLER_FINISHED;
4507		}
4508		break;
4509#else
4510		con->http_status = 501;
4511		return HANDLER_FINISHED;
4512#endif
4513	case HTTP_METHOD_WOL:{
4514
4515		buffer *wol_mac = NULL;
4516
4517		if (p->conf.is_readonly) {
4518			con->http_status = 403;
4519			return HANDLER_FINISHED;
4520		}
4521
4522		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "WOLMAC"))) {
4523			wol_mac = ds->value;
4524		} else {
4525			con->http_status = 400;
4526			return HANDLER_FINISHED;
4527		}
4528
4529		char cmd[BUFSIZ]="\0";
4530		sprintf(cmd, "ether-wake -i %s %s", srv->srvconf.arpping_interface->ptr, wol_mac->ptr);
4531		int rc = system(cmd);
4532
4533		if(rc!=0){
4534			con->http_status = 400;
4535			return HANDLER_FINISHED;
4536		}
4537
4538		Cdbg(DBE, "do HTTP_METHOD_WOL! %s rc=%d", cmd, rc);
4539
4540		con->http_status = 200;
4541		con->file_finished = 1;
4542
4543		return HANDLER_FINISHED;
4544	}
4545
4546	case HTTP_METHOD_GSL:{
4547#if EMBEDDED_EANBLE
4548		if(!con->srv_socket->is_ssl){
4549			con->http_status = 403;
4550			return HANDLER_FINISHED;
4551		}
4552#endif
4553
4554		buffer *buffer_url = NULL;
4555		buffer *buffer_filename = NULL;
4556		buffer *buffer_result_share_link = NULL;
4557		int expire = 1;
4558		int toShare = 1;
4559		Cdbg(DBE, "do HTTP_METHOD_GSL....................");
4560
4561		if (p->conf.is_readonly) {
4562			con->http_status = 403;
4563			return HANDLER_FINISHED;
4564		}
4565
4566		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "URL"))) {
4567			buffer_url = ds->value;
4568		} else {
4569			con->http_status = 400;
4570			return HANDLER_FINISHED;
4571		}
4572
4573		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "FILENAME"))) {
4574			buffer_filename = ds->value;
4575		} else {
4576			con->http_status = 400;
4577			return HANDLER_FINISHED;
4578		}
4579
4580		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "EXPIRE"))) {
4581			expire = atoi(ds->value->ptr);
4582		} else {
4583			con->http_status = 400;
4584			return HANDLER_FINISHED;
4585		}
4586
4587		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOSHARE"))) {
4588			toShare = atoi(ds->value->ptr);
4589		}
4590
4591		//- Check if exceed max sharelink count.
4592		int sharelink_save_count = get_sharelink_save_count();
4593		int file_count = 0;
4594		char* tmp_filename = strdup(buffer_filename->ptr);
4595		char *pch = strtok(tmp_filename, ";");
4596		while(pch!=NULL){
4597			file_count++;
4598			pch = strtok(NULL,";");
4599		}
4600		free(tmp_filename);
4601
4602		if(toShare==1&&sharelink_save_count+file_count>srv->srvconf.max_sharelink){
4603			con->http_status = 405;
4604			return HANDLER_FINISHED;
4605		}
4606
4607		char auth[100]="\0";
4608		if(con->smb_info)
4609			sprintf(auth, "%s:%s", con->smb_info->username->ptr, con->smb_info->password->ptr);
4610		else{
4611			con->http_status = 400;
4612			return HANDLER_FINISHED;
4613		}
4614
4615		char* base64_auth = ldb_base64_encode(auth, strlen(auth));
4616
4617		if( generate_sharelink(srv,
4618							   con,
4619							   buffer_filename->ptr,
4620							   buffer_url->ptr,
4621							   base64_auth,
4622							   expire,
4623							   toShare,
4624							   &buffer_result_share_link) == 0){
4625			free(base64_auth);
4626			con->http_status = 400;
4627			return HANDLER_FINISHED;
4628		}
4629
4630		con->http_status = 200;
4631
4632		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
4633
4634		b = buffer_init();
4635
4636		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
4637		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
4638		buffer_append_string_len(b,CONST_STR_LEN("<sharelink>"));
4639		buffer_append_string_buffer(b,buffer_result_share_link);
4640		buffer_append_string_len(b,CONST_STR_LEN("</sharelink>"));
4641		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
4642
4643		chunkqueue_append_buffer(con->write_queue, b);
4644		buffer_free(b);
4645
4646		con->file_finished = 1;
4647
4648		buffer_free(buffer_result_share_link);
4649		free(base64_auth);
4650
4651		if(toShare==1)
4652			save_sharelink_list();
4653
4654		return HANDLER_FINISHED;
4655	}
4656
4657	case HTTP_METHOD_GSLL:{
4658#if EMBEDDED_EANBLE
4659		if(!con->srv_socket->is_ssl){
4660			con->http_status = 403;
4661			return HANDLER_FINISHED;
4662		}
4663#endif
4664		Cdbg(DBE, "do HTTP_METHOD_GSLL....................");
4665
4666		buffer* encode_filename = NULL;
4667		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "ENCODE_FILENAME"))) {
4668			encode_filename = ds->value;
4669		}
4670
4671		share_link_info_t* c;
4672
4673		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
4674
4675		b = buffer_init();
4676
4677		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
4678		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
4679
4680		//- encode file name flag: 0: no encode, 1: encode
4681		buffer_append_string_len(b,CONST_STR_LEN("<encode_filename>"));
4682		if(!buffer_is_empty(encode_filename))
4683			buffer_append_string(b, encode_filename->ptr);
4684		else
4685			buffer_append_string(b, "0");
4686		buffer_append_string_len(b,CONST_STR_LEN("</encode_filename>"));
4687
4688		time_t cur_time = time(NULL);
4689
4690		for (c = share_link_info_list; c; c = c->next) {
4691
4692			if(c->toshare != 1)
4693				continue;
4694
4695			if( cur_time < c->createtime )
4696				continue;
4697
4698			double offset = difftime(c->expiretime, cur_time);
4699			if( c->expiretime!=0 && offset < 0.0 )
4700				continue;
4701
4702			buffer_append_string_len(b,CONST_STR_LEN("<sharelink"));
4703
4704			//- file name
4705			buffer_append_string_len(b,CONST_STR_LEN(" filename=\""));
4706
4707			if(encode_filename && buffer_is_equal_string(encode_filename, "1", 1))
4708			buffer_append_string_encoded(b, CONST_BUF_LEN(c->filename), ENCODING_REL_URI);
4709			else
4710				buffer_append_string_len(b, CONST_BUF_LEN(c->filename));
4711
4712			buffer_append_string_len(b,CONST_STR_LEN("\""));
4713
4714			//- share link url
4715			buffer_append_string_len(b,CONST_STR_LEN(" url=\""));
4716			buffer_append_string_buffer(b,c->shortpath);
4717			buffer_append_string_len(b,CONST_STR_LEN("\""));
4718
4719			//- expire time
4720			char strTime[25] = {0};
4721			if(c->expiretime!=0)
4722				strftime(strTime, sizeof(strTime), "%Y/%m/%d %H:%M:%S", localtime(&(c->expiretime)));
4723			else
4724				strcpy(strTime,"0");
4725
4726			buffer_append_string_len(b,CONST_STR_LEN(" expiretime=\""));
4727			buffer_append_string(b,strTime);
4728			buffer_append_string_len(b,CONST_STR_LEN("\""));
4729
4730			//- create time
4731			char strTime2[25] = {0};
4732			strftime(strTime2, sizeof(strTime2), "%Y/%m/%d %H:%M:%S", localtime(&(c->createtime)));
4733			buffer_append_string_len(b,CONST_STR_LEN(" createtime=\""));
4734			buffer_append_string(b,strTime2);
4735			buffer_append_string_len(b,CONST_STR_LEN("\""));
4736
4737			//- left time
4738			char strLeftTime[25] = {0};
4739			sprintf(strLeftTime,"%f",offset);
4740			buffer_append_string_len(b,CONST_STR_LEN(" lefttime=\""));
4741			if(c->expiretime!=0)
4742				buffer_append_string(b,strLeftTime);
4743			else
4744				buffer_append_string(b,"0");
4745			buffer_append_string_len(b,CONST_STR_LEN("\""));
4746
4747			buffer_append_string_len(b,CONST_STR_LEN("></sharelink>"));
4748		}
4749
4750		buffer_append_string_len(b,CONST_STR_LEN("</result>\n"));
4751
4752		chunkqueue_append_buffer(con->write_queue, b);
4753		buffer_free(b);
4754
4755		con->http_status = 200;
4756		con->file_finished = 1;
4757
4758		return HANDLER_FINISHED;
4759	}
4760
4761	case HTTP_METHOD_REMOVESL:{
4762#if EMBEDDED_EANBLE
4763		if(!con->srv_socket->is_ssl){
4764			con->http_status = 403;
4765			return HANDLER_FINISHED;
4766		}
4767#endif
4768
4769		Cdbg(DBE, "do HTTP_METHOD_REMOVESL....................");
4770
4771		buffer *buffer_share_link = NULL;
4772
4773		if (p->conf.is_readonly) {
4774			con->http_status = 403;
4775			return HANDLER_FINISHED;
4776		}
4777
4778		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "SHARELINK"))) {
4779			buffer_share_link = ds->value;
4780		} else {
4781			con->http_status = 400;
4782			return HANDLER_FINISHED;
4783		}
4784
4785		int b_save_arpping_list = 0;
4786		char * pch;
4787		pch = strtok(buffer_share_link->ptr, ";");
4788
4789		while(pch!=NULL){
4790
4791			share_link_info_t* c;
4792			for (c = share_link_info_list; c; c = c->next) {
4793
4794				if(c->toshare == 0)
4795					continue;
4796
4797				if(buffer_is_equal_string(c->shortpath, pch, strlen(pch))){
4798					free_share_link_info(c);
4799					DLIST_REMOVE(share_link_info_list, c);
4800					free(c);
4801					b_save_arpping_list = 1;
4802					break;
4803				}
4804			}
4805
4806			//- Next
4807			pch = strtok(NULL,";");
4808		}
4809
4810		if(b_save_arpping_list)
4811			save_sharelink_list();
4812
4813		con->http_status = 200;
4814		con->file_finished = 1;
4815
4816		return HANDLER_FINISHED;
4817	}
4818
4819	case HTTP_METHOD_GETSRVTIME:{
4820#if EMBEDDED_EANBLE
4821		if(!con->srv_socket->is_ssl){
4822			con->http_status = 403;
4823			return HANDLER_FINISHED;
4824		}
4825#endif
4826
4827		char stime[1024]="\0";
4828		time_t server_time = time(NULL);
4829		sprintf(stime, "%ld", server_time);
4830		Cdbg(DBE, "do HTTP_METHOD_GETSRVTIME....................%s", stime);
4831
4832		con->http_status = 200;
4833
4834		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
4835
4836		b = buffer_init();
4837
4838		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
4839		buffer_append_string_len(b,CONST_STR_LEN("<result>\n"));
4840		buffer_append_string_len(b,CONST_STR_LEN("<servertime>\n"));
4841		buffer_append_string(b,stime);
4842		buffer_append_string_len(b,CONST_STR_LEN("</servertime>\n"));
4843		buffer_append_string_len(b,CONST_STR_LEN("</result>\n"));
4844
4845		chunkqueue_append_buffer(con->write_queue, b);
4846		buffer_free(b);
4847
4848		con->file_finished = 1;
4849		return HANDLER_FINISHED;
4850	}
4851
4852	case HTTP_METHOD_GETROUTERMAC:{
4853
4854#if EMBEDDED_EANBLE
4855		char* router_mac = nvram_get_router_mac();
4856#else
4857		char router_mac[20]="\0";
4858		get_mac_address("eth0", &router_mac);
4859#endif
4860
4861		con->http_status = 200;
4862
4863		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
4864
4865		b = buffer_init();
4866
4867		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
4868		buffer_append_string_len(b,CONST_STR_LEN("<result>\n"));
4869		buffer_append_string_len(b,CONST_STR_LEN("<mac>\n"));
4870		buffer_append_string(b,router_mac);
4871		buffer_append_string_len(b,CONST_STR_LEN("</mac>\n"));
4872		buffer_append_string_len(b,CONST_STR_LEN("</result>\n"));
4873
4874		chunkqueue_append_buffer(con->write_queue, b);
4875		buffer_free(b);
4876
4877		con->file_finished = 1;
4878		#if EMBEDDED_EANBLE
4879		#ifdef APP_IPKG
4880        free(router_mac);
4881		#endif
4882        #endif
4883		return HANDLER_FINISHED;
4884	}
4885
4886	case HTTP_METHOD_GETFIRMVER:{
4887#if EMBEDDED_EANBLE
4888		if(!con->srv_socket->is_ssl){
4889			con->http_status = 403;
4890			return HANDLER_FINISHED;
4891		}
4892#endif
4893
4894#if EMBEDDED_EANBLE
4895		char* firmware_version = nvram_get_firmware_version();
4896		char* build_no = nvram_get_build_no();
4897#else
4898		char* firmware_version = "1.0.0";
4899		char* build_no = "0";
4900#endif
4901
4902		con->http_status = 200;
4903
4904		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
4905
4906		b = buffer_init();
4907
4908		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
4909		buffer_append_string_len(b,CONST_STR_LEN("<result>\n"));
4910		buffer_append_string_len(b,CONST_STR_LEN("<version>\n"));
4911		buffer_append_string(b,firmware_version);
4912		buffer_append_string(b,".");
4913		buffer_append_string(b,build_no);
4914		buffer_append_string_len(b,CONST_STR_LEN("</version>\n"));
4915		buffer_append_string_len(b,CONST_STR_LEN("</result>\n"));
4916
4917		chunkqueue_append_buffer(con->write_queue, b);
4918		buffer_free(b);
4919
4920		con->file_finished = 1;
4921#if EMBEDDED_EANBLE
4922#ifdef APP_IPKG
4923        free(firmware_version);
4924        free(build_no);
4925#endif
4926#endif
4927		return HANDLER_FINISHED;
4928	}
4929
4930	case HTTP_METHOD_GETROUTERINFO:{
4931#if EMBEDDED_EANBLE
4932		if(!con->srv_socket->is_ssl){
4933			con->http_status = 403;
4934			return HANDLER_FINISHED;
4935		}
4936#endif
4937
4938		Cdbg(DBE, "do HTTP_METHOD_GETROUTERINFO....................");
4939
4940		char stime[1024]="\0";
4941		time_t server_time = time(NULL);
4942		sprintf(stime, "%ld", server_time);
4943
4944#if EMBEDDED_EANBLE
4945		char* router_mac = nvram_get_router_mac();
4946
4947		char* firmware_version = nvram_get_firmware_version();
4948		char* build_no = nvram_get_build_no();
4949
4950		char* modal_name = nvram_get_productid();
4951
4952		//- Computer Name
4953		char* computer_name = nvram_get_computer_name();
4954		char* st_webdav_mode = nvram_get_st_webdav_mode();
4955		char* webdav_http_port = nvram_get_webdav_http_port();
4956		char* webdav_https_port = nvram_get_webdav_https_port();
4957		char* http_enable = nvram_get_http_enable();
4958		char* lan_http_port = "80";
4959		char* lan_https_port = nvram_get_lan_https_port();
4960		char* misc_http_x = nvram_get_misc_http_x();
4961		char* misc_http_port = nvram_get_misc_http_port();
4962		char* misc_https_port = nvram_get_misc_https_port();
4963		char* ddns_host_name = nvram_get_ddns_host_name();
4964		char* disk_path = "/mnt/";
4965		char* wan_ip = nvram_get_wan_ip();
4966		char *usbdiskname = nvram_get_productid();
4967
4968		//- Get aicloud version
4969		#ifdef APP_IPKG
4970		char* aicloud_version_file = "/opt/lib/ipkg/info/aicloud.control";
4971		char* aicloud_app_type = "install";
4972		char* smartsync_version_file = "/opt/lib/ipkg/info/smartsync.control";
4973		#else
4974		char* aicloud_version_file = "/usr/lighttpd/control";
4975		char* aicloud_app_type = "embed";
4976		char* smartsync_version_file = "/usr/lighttpd/smartsync_control";
4977		#endif
4978		char aicloud_version[30]="\0";
4979		char smartsync_version[30]="\0";
4980		char *swpjverno = nvram_get_swpjverno();
4981		char *extendno = nvram_get_extendno();
4982
4983		char *https_crt_cn = nvram_get_https_crt_cn();
4984
4985		char *aae_support = nvram_get_value("aae_support");
4986		char *aae_enable = nvram_get_value("aae_enable");
4987		char *aae_deviceid = nvram_get_value("aae_deviceid");
4988
4989		char *apps_sq = nvram_get_apps_sq();
4990
4991#ifdef USE_TCAPI
4992		char *is_dsl_platform = "1";
4993#else
4994		char *is_dsl_platform = "0";
4995#endif
4996
4997#else
4998		char router_mac[20]="\0";
4999		get_mac_address("eth0", &router_mac);
5000
5001		char* firmware_version = "1.0.0";
5002		char* build_no = "0";
5003
5004		char* modal_name = "usbdisk";
5005
5006		//- Computer Name
5007		char* computer_name = "WebDAV";
5008		char* st_webdav_mode = "0";
5009		char* webdav_http_port = "8082";
5010		char* webdav_https_port = "443";
5011		char* http_enable = "2";
5012		char* lan_http_port = "80";
5013		char* lan_https_port = "8443";
5014		char* misc_http_x = "0";
5015		char* misc_http_port = "8080";
5016		char* misc_https_port = "8443";
5017		char* ddns_host_name = "";
5018		char* disk_path = "/mnt/";
5019		char* wan_ip = "192.168.1.10";
5020		char *usbdiskname = "usbdisk";
5021
5022		//- Get aicloud version
5023		char* aicloud_version_file = "/usr/css/control";
5024		char* smartsync_version_file = "/usr/css/smartsync_control";
5025		char aicloud_version[30]="\0";
5026		char smartsync_version[30]="\0";
5027		char *swpjverno = "";
5028		char *extendno = "";
5029		char* aicloud_app_type = "embed";
5030
5031		char *https_crt_cn = "192.168.1.1";
5032
5033		char *aae_support = "0";
5034		char *aae_enable = "0";
5035		char *aae_deviceid = "";
5036
5037		char *apps_sq = "0";
5038		char *is_dsl_platform = "0";
5039#endif
5040		int sharelink_save_count = get_sharelink_save_count();
5041		int dms_enable = is_dms_enabled();
5042		int jffs_supported = is_jffs_supported();
5043
5044		if(buffer_is_empty(srv->srvconf.aicloud_version)){
5045			//- Parser version file
5046			FILE* fp2;
5047			char line[128];
5048			if((fp2 = fopen(aicloud_version_file, "r")) != NULL){
5049				memset(line, 0, sizeof(line));
5050				while(fgets(line, 128, fp2) != NULL){
5051					if(strncmp(line, "Version:", 8)==0){
5052						strncpy(aicloud_version, line + 9, strlen(line)-8);
5053						break;
5054					}
5055				}
5056				fclose(fp2);
5057			}
5058		}
5059		else{
5060			strcpy(aicloud_version, srv->srvconf.aicloud_version->ptr);
5061		}
5062
5063		if(buffer_is_empty(srv->srvconf.smartsync_version)){
5064			//- Parser version file
5065			FILE* fp2;
5066			char line[128];
5067			if((fp2 = fopen(smartsync_version_file, "r")) != NULL){
5068				memset(line, 0, sizeof(line));
5069				while(fgets(line, 128, fp2) != NULL){
5070					if(strncmp(line, "Version:", 8)==0){
5071						strncpy(smartsync_version, line + 9, strlen(line)-8);
5072						break;
5073					}
5074				}
5075				fclose(fp2);
5076			}
5077		}
5078		else{
5079			strcpy(smartsync_version, srv->srvconf.smartsync_version->ptr);
5080		}
5081
5082#ifndef APP_IPKG
5083		if( swpjverno!=NULL && strncmp(swpjverno,"", 1)!=0 ){
5084			strcpy(aicloud_version, swpjverno);
5085			if(extendno!=NULL && strncmp(extendno,"", 1)!=0)
5086			{
5087			    strcat(aicloud_version, "_");
5088			    strcat(aicloud_version, extendno);
5089		    }
5090		}
5091#endif
5092		con->http_status = 200;
5093
5094		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5095
5096		b = buffer_init();
5097
5098		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
5099		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
5100		buffer_append_string_len(b,CONST_STR_LEN("<servertime>"));
5101		buffer_append_string(b,stime);
5102		buffer_append_string_len(b,CONST_STR_LEN("</servertime>"));
5103		buffer_append_string_len(b,CONST_STR_LEN("<mac>"));
5104		buffer_append_string(b,router_mac);
5105		buffer_append_string_len(b,CONST_STR_LEN("</mac>"));
5106		buffer_append_string_len(b,CONST_STR_LEN("<version>"));
5107		buffer_append_string(b,firmware_version);
5108		buffer_append_string(b,".");
5109		buffer_append_string(b,build_no);
5110		buffer_append_string_len(b,CONST_STR_LEN("</version>"));
5111		buffer_append_string_len(b,CONST_STR_LEN("<aicloud_version>"));
5112		buffer_append_string(b,aicloud_version);
5113		buffer_append_string_len(b,CONST_STR_LEN("</aicloud_version>"));
5114		buffer_append_string_len(b,CONST_STR_LEN("<extendno>"));
5115		if(extendno!=NULL && strncmp(extendno,"", 1)!=0) buffer_append_string(b,extendno);
5116		buffer_append_string_len(b,CONST_STR_LEN("</extendno>"));
5117		buffer_append_string_len(b,CONST_STR_LEN("<aicloud_app_type>"));
5118		buffer_append_string(b,aicloud_app_type);
5119		buffer_append_string_len(b,CONST_STR_LEN("</aicloud_app_type>"));
5120		buffer_append_string_len(b,CONST_STR_LEN("<smartsync_version>"));
5121		buffer_append_string(b,smartsync_version);
5122		buffer_append_string_len(b,CONST_STR_LEN("</smartsync_version>"));
5123		buffer_append_string_len(b,CONST_STR_LEN("<modalname>"));
5124		buffer_append_string(b,modal_name);
5125		buffer_append_string_len(b,CONST_STR_LEN("</modalname>"));
5126		buffer_append_string_len(b,CONST_STR_LEN("<computername>"));
5127		buffer_append_string(b,computer_name);
5128		buffer_append_string_len(b,CONST_STR_LEN("</computername>"));
5129		buffer_append_string_len(b,CONST_STR_LEN("<usbdiskname>"));
5130		buffer_append_string(b,usbdiskname);
5131		buffer_append_string_len(b,CONST_STR_LEN("</usbdiskname>"));
5132		buffer_append_string_len(b,CONST_STR_LEN("<webdav_mode>"));
5133		buffer_append_string(b,st_webdav_mode);
5134		buffer_append_string_len(b,CONST_STR_LEN("</webdav_mode>"));
5135		buffer_append_string_len(b,CONST_STR_LEN("<http_port>"));
5136		buffer_append_string(b,webdav_http_port);
5137		buffer_append_string_len(b,CONST_STR_LEN("</http_port>"));
5138		buffer_append_string_len(b,CONST_STR_LEN("<https_port>"));
5139		buffer_append_string(b,webdav_https_port);
5140		buffer_append_string_len(b,CONST_STR_LEN("</https_port>"));
5141		buffer_append_string_len(b,CONST_STR_LEN("<http_enable>"));
5142		buffer_append_string(b,http_enable);
5143		buffer_append_string_len(b,CONST_STR_LEN("</http_enable>"));
5144		buffer_append_string_len(b,CONST_STR_LEN("<lan_http_port>"));
5145		buffer_append_string(b,lan_http_port);
5146		buffer_append_string_len(b,CONST_STR_LEN("</lan_http_port>"));
5147		buffer_append_string_len(b,CONST_STR_LEN("<lan_https_port>"));
5148		buffer_append_string(b,lan_https_port);
5149		buffer_append_string_len(b,CONST_STR_LEN("</lan_https_port>"));
5150		buffer_append_string_len(b,CONST_STR_LEN("<misc_http_enable>"));
5151		buffer_append_string(b,misc_http_x);
5152		buffer_append_string_len(b,CONST_STR_LEN("</misc_http_enable>"));
5153		buffer_append_string_len(b,CONST_STR_LEN("<misc_http_port>"));
5154		buffer_append_string(b,misc_http_port);
5155		buffer_append_string_len(b,CONST_STR_LEN("</misc_http_port>"));
5156		buffer_append_string_len(b,CONST_STR_LEN("<misc_https_port>"));
5157		buffer_append_string(b,misc_https_port);
5158		buffer_append_string_len(b,CONST_STR_LEN("</misc_https_port>"));
5159		buffer_append_string_len(b,CONST_STR_LEN("<aae_support>"));
5160		buffer_append_string(b,aae_support);
5161		buffer_append_string_len(b,CONST_STR_LEN("</aae_support>"));
5162		buffer_append_string_len(b,CONST_STR_LEN("<aae_enable>"));
5163		buffer_append_string(b,aae_enable);
5164		buffer_append_string_len(b,CONST_STR_LEN("</aae_enable>"));
5165		buffer_append_string_len(b,CONST_STR_LEN("<aae_deviceid>"));
5166		buffer_append_string(b,aae_deviceid);
5167		buffer_append_string_len(b,CONST_STR_LEN("</aae_deviceid>"));
5168		buffer_append_string_len(b,CONST_STR_LEN("<last_login_info>"));
5169		if(buffer_is_empty(srv->last_login_info))
5170			buffer_append_string(b,"");
5171		else
5172			buffer_append_string(b,srv->last_login_info->ptr);
5173		buffer_append_string_len(b,CONST_STR_LEN("</last_login_info>"));
5174		buffer_append_string_len(b,CONST_STR_LEN("<ddns_host_name>"));
5175		buffer_append_string(b,ddns_host_name);
5176		buffer_append_string_len(b,CONST_STR_LEN("</ddns_host_name>"));
5177		buffer_append_string_len(b,CONST_STR_LEN("<wan_ip>"));
5178		buffer_append_string(b,wan_ip);
5179		buffer_append_string_len(b,CONST_STR_LEN("</wan_ip>"));
5180		buffer_append_string_len(b,CONST_STR_LEN("<dms_enable>"));
5181		buffer_append_string(b, ((dms_enable==1) ? "1" : "0"));
5182		buffer_append_string_len(b,CONST_STR_LEN("</dms_enable>"));
5183		buffer_append_string_len(b,CONST_STR_LEN("<account_manager_enable>"));
5184		buffer_append_string(b, "0");
5185		buffer_append_string_len(b,CONST_STR_LEN("</account_manager_enable>"));
5186		buffer_append_string_len(b,CONST_STR_LEN("<https_crt_cn>"));
5187		buffer_append_string(b,https_crt_cn);
5188		buffer_append_string_len(b,CONST_STR_LEN("</https_crt_cn>"));
5189		buffer_append_string_len(b,CONST_STR_LEN("<app_installation_url>"));
5190		buffer_append_string(b, buffer_is_empty(srv->srvconf.app_installation_url) ? "" : srv->srvconf.app_installation_url->ptr);
5191		buffer_append_string_len(b,CONST_STR_LEN("</app_installation_url>"));
5192		buffer_append_string_len(b,CONST_STR_LEN("<apps_sq>"));
5193		buffer_append_string(b,apps_sq);
5194		buffer_append_string_len(b,CONST_STR_LEN("</apps_sq>"));
5195		buffer_append_string_len(b,CONST_STR_LEN("<is_dsl_platform>"));
5196		buffer_append_string(b,is_dsl_platform);
5197		buffer_append_string_len(b,CONST_STR_LEN("</is_dsl_platform>"));
5198
5199		buffer_append_string_len(b,CONST_STR_LEN("<used_sharelink>"));
5200		buffer_append_int(b, sharelink_save_count);
5201		buffer_append_string_len(b,CONST_STR_LEN("</used_sharelink>"));
5202
5203		buffer_append_string_len(b,CONST_STR_LEN("<max_sharelink>"));
5204		buffer_append_int(b, srv->srvconf.max_sharelink);
5205		buffer_append_string_len(b,CONST_STR_LEN("</max_sharelink>"));
5206
5207		buffer_append_string_len(b,CONST_STR_LEN("<auto_close_streaming_port>1</auto_close_streaming_port>"));
5208		buffer_append_string_len(b,CONST_STR_LEN("<is_streaming_port_opend>"));
5209		buffer_append_int(b, srv->is_streaming_port_opend);
5210		buffer_append_string_len(b,CONST_STR_LEN("</is_streaming_port_opend>"));
5211
5212		DIR *dir;
5213		if (NULL != (dir = opendir(disk_path))) {
5214
5215			buffer_append_string_len(b,CONST_STR_LEN("<disk_space>"));
5216
5217			struct dirent *de;
5218
5219			while(NULL != (de = readdir(dir))) {
5220
5221				if ( de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0' ) {
5222					continue;
5223					//- ignore the parent dir
5224				}
5225
5226				if ( de->d_name[0] == '.' ) {
5227					continue;
5228					//- ignore the hidden file
5229				}
5230
5231				buffer_append_string_len(b,CONST_STR_LEN("<item>"));
5232
5233				char querycmd[100] = "\0";
5234
5235				sprintf(querycmd, "df|grep -i '%s%s'", disk_path, de->d_name);
5236
5237				buffer_append_string_len(b,CONST_STR_LEN("<DiskName>"));
5238				buffer_append_string(b,de->d_name);
5239				buffer_append_string_len(b,CONST_STR_LEN("</DiskName>"));
5240
5241				char mybuffer[BUFSIZ]="\0";
5242				FILE* fp = popen( querycmd, "r");
5243				if(fp){
5244					int len = fread(mybuffer, sizeof(char), BUFSIZ, fp);
5245					mybuffer[len-1]="\0";
5246					pclose(fp);
5247
5248					char * pch;
5249					pch = strtok(mybuffer, " ");
5250					int count=1;
5251					while(pch!=NULL){
5252						if(count==3){
5253							buffer_append_string_len(b,CONST_STR_LEN("<DiskUsed>"));
5254							buffer_append_string(b,pch);
5255							buffer_append_string_len(b,CONST_STR_LEN("</DiskUsed>"));
5256						}
5257						else if(count==4){
5258							buffer_append_string_len(b,CONST_STR_LEN("<DiskAvailable>"));
5259							buffer_append_string(b,pch);
5260							buffer_append_string_len(b,CONST_STR_LEN("</DiskAvailable>"));
5261						}
5262						else if(count==5){
5263							buffer_append_string_len(b,CONST_STR_LEN("<DiskUsedPercent>"));
5264							buffer_append_string(b,pch);
5265							buffer_append_string_len(b,CONST_STR_LEN("</DiskUsedPercent>"));
5266						}
5267
5268						//- Next
5269						pch = strtok(NULL," ");
5270						count++;
5271					}
5272
5273				}
5274
5275				buffer_append_string_len(b,CONST_STR_LEN("</item>"));
5276			}
5277
5278			buffer_append_string_len(b,CONST_STR_LEN("</disk_space>"));
5279
5280			closedir(dir);
5281		}
5282
5283		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
5284
5285		chunkqueue_append_buffer(con->write_queue, b);
5286		buffer_free(b);
5287
5288		con->file_finished = 1;
5289#if EMBEDDED_EANBLE
5290#ifdef APP_IPKG
5291        free(router_mac);
5292
5293        free(firmware_version);
5294        free(build_no);
5295
5296        //- Computer Name
5297        free(modal_name);
5298        free(computer_name);
5299        free(st_webdav_mode);
5300        free(webdav_http_port);
5301        free(webdav_https_port);
5302        free(misc_http_x);
5303        free(misc_http_port);
5304        free(ddns_host_name);
5305		free(wan_ip);
5306		free(http_enable);
5307		free(misc_https_port);
5308		free(usbdiskname);
5309		if( swpjverno!=NULL && strncmp(swpjverno,"", 1)!=0 )
5310		{
5311			free(swpjverno);
5312		}
5313		if( extendno != NULL)
5314		{
5315			free(extendno);
5316		}
5317		free(https_crt_cn);
5318#endif
5319#endif
5320		return HANDLER_FINISHED;
5321	}
5322
5323	case HTTP_METHOD_GETNOTICE:{
5324		if(!con->srv_socket->is_ssl){
5325			con->http_status = 403;
5326			return HANDLER_FINISHED;
5327		}
5328
5329		buffer* timestamp = NULL;
5330		char log_file[200] = "/tmp/aicloud_notice.log";
5331
5332		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TIMESTAMP"))) {
5333			timestamp = ds->value;
5334		} else {
5335			con->http_status = 400;
5336			return HANDLER_FINISHED;
5337		}
5338
5339		Cdbg(1, "do HTTP_METHOD_GETNOTICE....................log_file=%s", log_file);
5340		unlink(log_file);
5341
5342#if 0
5343		#if EMBEDDED_EANBLE
5344		#if HAVE_PUSHLOG
5345		getlogbytimestr(log_file, timestamp->ptr, 1);
5346		#endif
5347		#endif
5348#endif
5349
5350		if( !file_exist(log_file) ||
5351			file_size(log_file) == 0 ){
5352			con->http_status = 404;
5353			con->file_finished = 1;
5354			return HANDLER_FINISHED;
5355		}
5356
5357		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5358
5359		b = buffer_init();
5360
5361		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
5362		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
5363		buffer_append_string_len(b,CONST_STR_LEN("<log>"));
5364
5365		FILE* fp = fopen(log_file, "rb");
5366
5367		if(fp!=NULL){
5368			 //Get file length
5369        	fseek(fp, 0, SEEK_END);
5370        	int fileLen = ftell(fp);
5371        	fseek(fp, 0, SEEK_SET);
5372
5373			char* log_content = (char *)malloc(fileLen+1);
5374			if(!log_content){
5375				fclose(fp);
5376				con->http_status = 404;
5377				con->file_finished = 1;
5378				return HANDLER_FINISHED;
5379			}
5380
5381			fread( log_content, fileLen, sizeof(unsigned char), fp );
5382
5383			buffer_append_string_len(b, log_content, fileLen);
5384
5385			Cdbg(1, "log_content=%s", log_content);
5386
5387			free(log_content);
5388
5389			fclose(fp);
5390		}
5391
5392		buffer_append_string_len(b,CONST_STR_LEN("</log>"));
5393		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
5394
5395		chunkqueue_append_buffer(con->write_queue, b);
5396		buffer_free(b);
5397
5398		con->http_status = 200;
5399		con->file_finished = 1;
5400		return HANDLER_FINISHED;
5401	}
5402
5403	case HTTP_METHOD_RESCANSMBPC:{
5404#if EMBEDDED_EANBLE
5405		if(!con->srv_socket->is_ssl){
5406			con->http_status = 403;
5407			return HANDLER_FINISHED;
5408		}
5409#endif
5410
5411		Cdbg(DBE, "do HTTP_METHOD_RESCANSMBPC");
5412
5413		stop_arpping_process();
5414
5415		#if EMBEDDED_EANBLE
5416		nvram_set_smbdav_str("");
5417		#else
5418		unlink("/tmp/arpping_list");
5419		#endif
5420
5421		con->http_status = 200;
5422		con->file_finished = 1;
5423		return HANDLER_FINISHED;
5424	}
5425
5426	case HTTP_METHOD_LOGOUT:{
5427#if EMBEDDED_EANBLE
5428		if(!con->srv_socket->is_ssl){
5429			con->http_status = 403;
5430			return HANDLER_FINISHED;
5431		}
5432#endif
5433		Cdbg(DBE, "do HTTP_METHOD_LOGOUT %s", con->smb_info->server);
5434
5435		//- Find router user name
5436		//- Get user-Agent
5437		data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
5438		if(ds==NULL){
5439			con->http_status = 400;
5440			con->file_finished = 1;
5441			return HANDLER_FINISHED;
5442		}
5443
5444		smb_info_t *c;
5445		for (c = srv->smb_srv_info_list; c; c = c->next) {
5446
5447			if( buffer_is_equal(c->asus_token, con->asus_token) &&
5448				buffer_is_equal(c->user_agent, ds->value) &&
5449			    buffer_is_equal(c->src_ip, con->dst_addr_buf) &&
5450			    buffer_is_equal(c->server, con->smb_info->server) ){
5451
5452				Cdbg(DBE, "RELOGIN c->server=[%s], c->user=[%s] c->pass=[%s]", c->server->ptr, c->username->ptr, c->password->ptr);
5453
5454				//buffer_copy_string(c->username, "RELOGIN");
5455				//buffer_copy_string(c->password, "");
5456
5457			#if 1
5458				buffer_free(c->username);
5459				buffer_free(c->password);
5460				buffer_free(c->workgroup);
5461				buffer_free(c->server);
5462				buffer_free(c->share);
5463				buffer_free(c->path);
5464				buffer_free(c->user_agent);
5465				buffer_free(c->src_ip);
5466				buffer_free(c->asus_token);
5467
5468				DLIST_REMOVE(srv->smb_srv_info_list, c);
5469				//free(c);
5470			#endif
5471
5472				break;
5473			}
5474
5475		}
5476
5477		con->http_status = 200;
5478		con->file_finished = 1;
5479		return HANDLER_FINISHED;
5480	}
5481
5482	case HTTP_METHOD_GETLATESTVER:{
5483#if EMBEDDED_EANBLE
5484		if(!con->srv_socket->is_ssl){
5485			con->http_status = 403;
5486			return HANDLER_FINISHED;
5487		}
5488#endif
5489
5490#if EMBEDDED_EANBLE
5491
5492#ifdef USE_TCAPI
5493		system("/usr/script/webs_update.sh");
5494#else
5495		system("/usr/sbin/webs_update.sh");
5496#endif
5497
5498		char* newest_version = nvram_get_latest_version();
5499		int webs_state_error = nvram_get_webs_state_error();
5500#else
5501		char* newest_version = "3004_110";
5502		int webs_state_error = 0;
5503#endif
5504
5505		if(webs_state_error==1){
5506			con->http_status = 400;
5507		}
5508		else{
5509			con->http_status = 200;
5510
5511			response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5512
5513			b = buffer_init();
5514
5515			buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
5516			buffer_append_string_len(b,CONST_STR_LEN("<result>"));
5517			buffer_append_string_len(b,CONST_STR_LEN("<version>"));
5518			buffer_append_string(b,newest_version);
5519			buffer_append_string_len(b,CONST_STR_LEN("</version>"));
5520			buffer_append_string_len(b,CONST_STR_LEN("</result>"));
5521
5522			chunkqueue_append_buffer(con->write_queue, b);
5523			buffer_free(b);
5524		}
5525
5526		con->file_finished = 1;
5527#if EMBEDDED_EANBLE
5528#ifdef APP_IPKG
5529		free(newest_version);
5530#endif
5531#endif
5532		return HANDLER_FINISHED;
5533	}
5534
5535	case HTTP_METHOD_GETDISKSPACE:{
5536		Cdbg(DBE, "do HTTP_METHOD_GETDISKSPACE");
5537
5538#if EMBEDDED_EANBLE
5539		if(!con->srv_socket->is_ssl){
5540			con->http_status = 403;
5541			return HANDLER_FINISHED;
5542		}
5543#endif
5544
5545		buffer *buffer_disk = NULL;
5546
5547		if (p->conf.is_readonly) {
5548			con->http_status = 403;
5549			return HANDLER_FINISHED;
5550		}
5551
5552		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "DISKNAME"))) {
5553			buffer_disk = ds->value;
5554		} else {
5555			con->http_status = 400;
5556			return HANDLER_FINISHED;
5557		}
5558
5559		int len = buffer_disk->size+10;
5560		char* disk_path = (char*)malloc(len);
5561		memset(disk_path, '\0', len);
5562#if EMBEDDED_EANBLE
5563		strcpy(disk_path, "/mnt/");
5564#else
5565		strcpy(disk_path, "/dev/");
5566#endif
5567		strcat(disk_path, buffer_disk->ptr);
5568
5569		if (-1 == stat(disk_path, &st)) {
5570			free(disk_path);
5571			con->http_status = 400;
5572			return HANDLER_FINISHED;
5573		}
5574		else if (!S_ISDIR(st.st_mode)) {
5575		   free(disk_path);
5576		   con->http_status = 400;
5577		   return HANDLER_FINISHED;
5578		}
5579
5580		char querycmd[100] = "\0";
5581		sprintf(querycmd, "df |grep -i %s", disk_path);
5582		free(disk_path);
5583
5584		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5585
5586		b = buffer_init();
5587
5588		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
5589		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
5590
5591		buffer_append_string_len(b,CONST_STR_LEN("<DiskName>"));
5592		buffer_append_string_buffer(b,buffer_disk);
5593		buffer_append_string_len(b,CONST_STR_LEN("</DiskName>"));
5594
5595		char mybuffer[BUFSIZ]="\0";
5596		FILE* fp = popen( querycmd, "r");
5597		if(fp){
5598			int len = fread(mybuffer, sizeof(char), BUFSIZ, fp);
5599			mybuffer[len-1]="\0";
5600			pclose(fp);
5601
5602			char * pch;
5603			pch = strtok(mybuffer, " ");
5604			int count=1;
5605			while(pch!=NULL){
5606				if(count==3){
5607					buffer_append_string_len(b,CONST_STR_LEN("<DiskUsed>"));
5608					buffer_append_string(b,pch);
5609					buffer_append_string_len(b,CONST_STR_LEN("</DiskUsed>"));
5610				}
5611				else if(count==4){
5612					buffer_append_string_len(b,CONST_STR_LEN("<DiskAvailable>"));
5613					buffer_append_string(b,pch);
5614					buffer_append_string_len(b,CONST_STR_LEN("</DiskAvailable>"));
5615				}
5616				else if(count==5){
5617					buffer_append_string_len(b,CONST_STR_LEN("<DiskUsedPercent>"));
5618					buffer_append_string(b,pch);
5619					buffer_append_string_len(b,CONST_STR_LEN("</DiskUsedPercent>"));
5620				}
5621
5622				//- Next
5623				pch = strtok(NULL," ");
5624				count++;
5625			}
5626
5627		}
5628
5629		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
5630
5631		chunkqueue_append_buffer(con->write_queue, b);
5632		buffer_free(b);
5633
5634		con->http_status = 200;
5635		con->file_finished = 1;
5636		return HANDLER_FINISHED;
5637	}
5638
5639#if 0
5640	case HTTP_METHOD_PROPFINDMEDIALIST:{
5641
5642#ifdef USE_MINIDLNA_DB
5643		//- 20130304 JerryLin add
5644		Cdbg(DBE, "do HTTP_METHOD_PROPFINDMEDIALIST");
5645		if (!p->conf.sql_minidlna) {
5646
5647			if (!buffer_is_empty(p->conf.sqlite_minidlna_db_name)) {
5648				Cdbg(DBE, "p->conf.sqlite_minidlna_db_name=%s", p->conf.sqlite_minidlna_db_name->ptr);
5649				if (SQLITE_OK != sqlite3_open(p->conf.sqlite_minidlna_db_name->ptr, &(p->conf.sql_minidlna))) {
5650					log_error_write(srv, __FILE__, __LINE__, "sbs", "sqlite3_open failed for",
5651							p->conf.sqlite_minidlna_db_name,
5652							sqlite3_errmsg(p->conf.sql_minidlna));
5653					Cdbg(DBE, "Fail to open minidlna db %s", p->conf.sqlite_minidlna_db_name->ptr);
5654				}
5655			}
5656
5657			if (!p->conf.sql_minidlna) {
5658				con->http_status = 403;
5659				con->file_finished = 1;
5660				return HANDLER_FINISHED;
5661			}
5662		}
5663
5664		sqlite3 *sql_minidlna = p->conf.sql_minidlna;
5665		/*
5666		int a, v, p;
5667		a = sql_get_int_field(sql_minidlna, "SELECT count(*) from DETAILS where MIME glob 'a*'");
5668		v = sql_get_int_field(sql_minidlna, "SELECT count(*) from DETAILS where MIME glob 'v*'");
5669		p = sql_get_int_field(sql_minidlna, "SELECT count(*) from DETAILS where MIME glob 'i*'");
5670
5671		Cdbg(DBE, "aaaaaaaaaaaaaaaaaaaaaaaaaaa audio=%d, video=%d, image=%d", a, v, p);
5672		*/
5673		int rows, i;
5674		char **result;
5675		sqlite_int64 plID, detailID;
5676		char *plpath, *plname, *fname, *last_dir;
5677		char sql_buf[] = "SELECT ID, PATH, TITLE from DETAILS where MIME glob 'a*'";
5678		if( sql_get_table(sql_minidlna, sql_buf, &result, &rows, NULL) != SQLITE_OK )
5679			return -1;
5680		if( !rows )
5681		{
5682			sqlite3_free_table(result);
5683			return 0;
5684		}
5685		rows++;
5686
5687		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5688
5689		b = chunkqueue_get_append_buffer(con->write_queue);
5690
5691		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
5692		buffer_append_string_len(b,CONST_STR_LEN("<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\" "));
5693		buffer_append_string_len(b,CONST_STR_LEN(">\n"));
5694
5695		char* usbdisk_name;
5696		#if EMBEDDED_EANBLE
5697		char *a = nvram_get_productid();
5698		int l = strlen(a)+1;
5699		usbdisk_name = (char*)malloc(l);
5700		memset(usbdisk_name,'\0', l);
5701		strcpy(usbdisk_name, a);
5702		#ifdef APP_IPKG
5703		free(a);
5704		#endif
5705		#else
5706		usbdisk_name = (char*)malloc(8);
5707		memset(usbdisk_name,'\0', 8);
5708		strcpy(usbdisk_name, "usbdisk");
5709		#endif
5710
5711		for( i=3; i<rows*3; i++ )
5712		{
5713			plID = strtoll(result[i], NULL, 10);
5714			plpath = result[++i];
5715			plname = result[++i];
5716
5717			char buff[4096];
5718			char* tmp = replace_str(&plpath[0],
5719			                    "tmp/mnt",
5720			                    usbdisk_name,
5721				                (char *)&buff[0]);
5722
5723			buffer_append_string_len(b,CONST_STR_LEN("<D:response>\n"));
5724			buffer_append_string_len(b,CONST_STR_LEN("<D:href>"));
5725			buffer_append_string_buffer(b, con->uri.scheme);
5726			buffer_append_string_len(b,CONST_STR_LEN("://"));
5727			buffer_append_string_buffer(b, con->uri.authority);
5728			buffer_append_string_encoded(b, tmp, strlen(tmp), ENCODING_REL_URI);
5729			buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
5730
5731			buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
5732			buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
5733
5734			//buffer_append_string_buffer(b, prop_200);
5735
5736			buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
5737			buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 200 OK</D:status>\n"));
5738			buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
5739
5740			buffer_append_string_len(b,CONST_STR_LEN("</D:response>\n"));
5741		}
5742
5743		buffer_append_string_len(b,CONST_STR_LEN("</D:multistatus>\n"));
5744
5745		Cdbg(DBE, "rows=%d", rows);
5746
5747		sqlite3_free_table(result);
5748#endif
5749
5750		con->http_status = 207;
5751		con->file_finished = 1;
5752		return HANDLER_FINISHED;
5753	}
5754#endif
5755
5756	case HTTP_METHOD_GETPRODUCTICON:{
5757#if EMBEDDED_EANBLE
5758		if(!con->srv_socket->is_ssl){
5759			con->http_status = 403;
5760			return HANDLER_FINISHED;
5761		}
5762#endif
5763		Cdbg(DBE, "do HTTP_METHOD_GETPRODUCTICON %s", srv->srvconf.product_image->ptr);
5764
5765		char product_icon_file[1024] = "\0";
5766
5767		char* odmpid = NULL;
5768		char* color = NULL;
5769		char *productid = NULL;
5770
5771		#if EMBEDDED_EANBLE
5772		odmpid = nvram_get_odmpid();
5773		color = nvram_get_value("color");
5774		productid = nvram_get_value("productid");
5775		#endif
5776
5777		if(!buffer_is_empty(srv->srvconf.product_image))
5778			strcpy(product_icon_file, srv->srvconf.product_image->ptr);
5779		else{
5780			if(color!=NULL&&strcmp(color, "")!=0){
5781
5782				strcpy(product_icon_file, "/www/images/Model_product_");
5783				strcat(product_icon_file, color);
5784				strcat(product_icon_file, ".png");
5785			}
5786			else if(odmpid!=NULL&&strcmp(odmpid, "")!=0){
5787
5788				if(productid!=NULL&&strcmp(productid, odmpid)==0){
5789					strcpy(product_icon_file, "/www/images/Model_product.png");
5790				}
5791				else{
5792					strcpy(product_icon_file, "/www/images/");
5793					strcat(product_icon_file, odmpid);
5794					strcat(product_icon_file, "Model_product.png");
5795				}
5796
5797			}
5798			else
5799				strcpy(product_icon_file, "/www/images/Model_product.png");
5800		}
5801
5802		#if EMBEDDED_EANBLE
5803		#ifdef APP_IPKG
5804		if(odmpid!=NULL) free(odmpid);
5805		if(color!=NULL) free(color);
5806		if(productid!=NULL) free(productid);
5807		#endif
5808		#endif
5809
5810		FILE* fp = fopen(product_icon_file, "rb");
5811
5812		if(fp!=NULL){
5813			 //Get file length
5814        	fseek(fp, 0, SEEK_END);
5815        	int fileLen = ftell(fp);
5816        	fseek(fp, 0, SEEK_SET);
5817
5818			char* buffer = (char *)malloc(fileLen+1);
5819			if(!buffer){
5820				con->http_status = 404;
5821				con->file_finished = 1;
5822				return HANDLER_FINISHED;
5823			}
5824
5825			char* aa = get_filename_ext(product_icon_file);
5826			int len = strlen(aa)+1;
5827			char* file_ext = (char*)malloc(len);
5828			memset(file_ext,'\0', len);
5829			strcpy(file_ext, aa);
5830			for (int i = 0; file_ext[i]; i++)
5831				file_ext[i] = tolower(file_ext[i]);
5832
5833			fread( buffer, fileLen, sizeof(unsigned char), fp );
5834
5835			char* base64_image = ldb_base64_encode(buffer, fileLen);
5836
5837			response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5838
5839			b = buffer_init();
5840
5841			buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
5842			buffer_append_string_len(b,CONST_STR_LEN("<result>"));
5843
5844			if( strcmp(file_ext,"jpg")==0 || strcmp(file_ext,"jpeg")==0 )
5845				buffer_append_string_len(b,CONST_STR_LEN("<mimetype>image/jpeg</mimetype>"));
5846			else if( strcmp(file_ext,"png")==0 )
5847				buffer_append_string_len(b,CONST_STR_LEN("<mimetype>image/png</mimetype>"));
5848			else if( strcmp(file_ext,"gif")==0 )
5849				buffer_append_string_len(b,CONST_STR_LEN("<mimetype>image/gif</mimetype>"));
5850			else
5851				buffer_append_string_len(b,CONST_STR_LEN("<mimetype>unknown</mimetype>"));
5852
5853			buffer_append_string_len(b,CONST_STR_LEN("<product_icon>"));
5854			buffer_append_string(b,base64_image);
5855			buffer_append_string_len(b,CONST_STR_LEN("</product_icon>"));
5856			buffer_append_string_len(b,CONST_STR_LEN("</result>"));
5857
5858			chunkqueue_append_buffer(con->write_queue, b);
5859			buffer_free(b);
5860
5861			free(file_ext);
5862			free(buffer);
5863			fclose(fp);
5864		}
5865		else{
5866			con->http_status = 404;
5867			con->file_finished = 1;
5868			return HANDLER_FINISHED;
5869		}
5870
5871		con->http_status = 200;
5872		con->file_finished = 1;
5873		return HANDLER_FINISHED;
5874	}
5875
5876	case HTTP_METHOD_GETVIDEOSUBTITLE:{
5877#if EMBEDDED_EANBLE
5878		if(!con->srv_socket->is_ssl){
5879			con->http_status = 403;
5880			return HANDLER_FINISHED;
5881		}
5882#endif
5883
5884		buffer* filename = NULL;
5885
5886		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "FILENAME"))) {
5887			filename = ds->value;
5888		} else {
5889			con->http_status = 400;
5890			return HANDLER_FINISHED;
5891		}
5892
5893		Cdbg(DBE, "do HTTP_METHOD_GETVIDEOSUBTITLE %s, filename=%s, con->physical.path=%s",
5894				con->url.path->ptr, filename->ptr, con->physical.path->ptr);
5895
5896		char auth[100]="\0";
5897		if(con->smb_info)
5898			sprintf(auth, "%s:%s", con->smb_info->username->ptr, con->smb_info->password->ptr);
5899		else{
5900			con->http_status = 400;
5901			return HANDLER_FINISHED;
5902		}
5903
5904		char* base64_auth = ldb_base64_encode(auth, strlen(auth));
5905
5906		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
5907
5908		b = buffer_init();
5909
5910		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
5911		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
5912
5913		if (NULL != (dir = smbc_wrapper_opendir(con, con->url.path->ptr))) {
5914			struct smbc_dirent *de;
5915
5916			while(NULL != (de = smbc_wrapper_readdir(con, dir))) {
5917
5918				if ((de->name[0] == '.' && de->name[1] == '\0')  ||
5919				    (de->name[0] == '.' && de->name[1] == '.' && de->name[2] == '\0')) {
5920					continue;
5921					/* ignore the parent dir */
5922				}
5923
5924				char* aa = get_filename_ext(de->name);
5925				int len = strlen(aa)+1;
5926				char* file_ext = (char*)malloc(len);
5927				memset(file_ext,'\0', len);
5928				strcpy(file_ext, aa);
5929				for (int i = 0; file_ext[i]; i++)
5930					file_ext[i] = tolower(file_ext[i]);
5931
5932				if( strcmp(file_ext, "srt")==0 &&
5933					strstr(de->name, filename->ptr) ){
5934
5935					buffer* buffer_filepath = buffer_init();
5936					buffer_copy_string(buffer_filepath, "");
5937					buffer_append_string_encoded(buffer_filepath, con->physical.rel_path->ptr, strlen(con->physical.rel_path->ptr), ENCODING_REL_URI);
5938
5939					buffer* buffer_result_share_link;
5940					if( generate_sharelink(srv,
5941						                   con,
5942						                   de->name,
5943						                   buffer_filepath->ptr,
5944						                   base64_auth, 0, 0,
5945						                   &buffer_result_share_link) == 1){
5946						buffer_append_string_len(b,CONST_STR_LEN("<file>"));
5947						buffer_append_string_len(b,CONST_STR_LEN("<name>"));
5948						buffer_append_string(b,de->name);
5949						buffer_append_string_len(b,CONST_STR_LEN("</name>"));
5950						buffer_append_string_len(b,CONST_STR_LEN("<sharelink>"));
5951						buffer_append_string_buffer(b,buffer_result_share_link);
5952						buffer_append_string_len(b,CONST_STR_LEN("</sharelink>"));
5953						buffer_append_string_len(b,CONST_STR_LEN("</file>"));
5954					}
5955
5956					buffer_free(buffer_filepath);
5957					buffer_free(buffer_result_share_link);
5958				}
5959
5960				free(file_ext);
5961
5962			}
5963
5964			smbc_wrapper_closedir(con, dir);
5965		}
5966
5967		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
5968
5969		chunkqueue_append_buffer(con->write_queue, b);
5970		buffer_free(b);
5971
5972		con->http_status = 200;
5973		con->file_finished = 1;
5974		return HANDLER_FINISHED;
5975	}
5976
5977	case HTTP_METHOD_GENROOTCERTIFICATE:{
5978
5979#if EMBEDDED_EANBLE
5980		if(!con->srv_socket->is_ssl){
5981			con->http_status = 403;
5982			return HANDLER_FINISHED;
5983		}
5984#endif
5985
5986		buffer* keylength = NULL; //- Private key length
5987		buffer* caname = NULL; //- CA name
5988		buffer* email = NULL; //- email address
5989		buffer* country = NULL; //- Country Name(2 letter code)
5990		buffer* state = NULL; //- State or Province Name(full name)
5991		buffer* ln = NULL; //- Locality Name(eg, city)
5992		buffer* orag = NULL; //- Organization Name(eg, company)
5993		buffer* ounit = NULL; //- Organizational Unit Name(eg, section)
5994		buffer* cn = NULL; //- Common Name(eg. your name or your server's hostname)
5995	#if 0
5996		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "KEYLEN"))) {
5997			keylength = ds->value;
5998		} else {
5999			con->http_status = 400;
6000			return HANDLER_FINISHED;
6001		}
6002
6003		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "CANAME"))) {
6004			caname = ds->value;
6005		} else {
6006			con->http_status = 400;
6007			return HANDLER_FINISHED;
6008		}
6009
6010		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "EMAIL"))) {
6011			email = ds->value;
6012		} else {
6013			con->http_status = 400;
6014			return HANDLER_FINISHED;
6015		}
6016
6017		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "COUNTRY"))) {
6018			country = ds->value;
6019		} else {
6020			con->http_status = 400;
6021			return HANDLER_FINISHED;
6022		}
6023
6024		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "STATE"))) {
6025			state = ds->value;
6026		} else {
6027			con->http_status = 400;
6028			return HANDLER_FINISHED;
6029		}
6030
6031		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "LN"))) {
6032			ln = ds->value;
6033		} else {
6034			con->http_status = 400;
6035			return HANDLER_FINISHED;
6036		}
6037
6038		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "ORAG"))) {
6039			orag = ds->value;
6040		} else {
6041			con->http_status = 400;
6042			return HANDLER_FINISHED;
6043		}
6044
6045		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "OUNIT"))) {
6046			ounit = ds->value;
6047		} else {
6048			con->http_status = 400;
6049			return HANDLER_FINISHED;
6050		}
6051	#endif
6052		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "CN"))) {
6053			cn = ds->value;
6054		} else {
6055			con->http_status = 400;
6056			return HANDLER_FINISHED;
6057		}
6058
6059		Cdbg(DBE, "nvram_set_https_crt_cn %s", cn->ptr);
6060
6061	#if EMBEDDED_EANBLE
6062
6063		nvram_set_https_crt_cn(cn->ptr);
6064
6065		unlink("/etc/cert.pem");
6066        unlink("/etc/key.pem");
6067
6068		Cdbg(DBE, "run gencert.sh");
6069		unsigned long long sn;
6070		char t[32];
6071		f_read("/dev/urandom", &sn, sizeof(sn));
6072		sprintf(t, "%llu", sn & 0x7FFFFFFFFFFFFFFFULL);
6073        int flag_cert=0;
6074
6075	#ifdef APP_IPKG
6076        char *cmd_app=NULL;
6077        cmd_app=(char *)malloc(sizeof(char)*(strlen(t)+64));
6078        memset(cmd_app,'\0',sizeof(cmd_app));
6079        sprintf(cmd_app,"%s %s","/opt/etc/apps_asus_script/gencert.sh",t);
6080        system(cmd_app);
6081        while(-1==access("/etc/cert.pem",F_OK)||-1==access("/etc/key.pem",F_OK))
6082        {
6083        	usleep(1000*100);
6084        }
6085        free(cmd_app);
6086
6087        Cdbg(DBE, "tar -zcvf certification");
6088        system("tar -C / -czf /tmp/cert.tgz etc/cert.pem etc/key.pem");
6089        while(-1==access("/tmp/cert.tgz",F_OK))
6090        {
6091        	usleep(1000*100);
6092        }
6093        flag_cert=1;
6094	#else
6095        eval("gencert.sh", t);
6096
6097		Cdbg(DBE, "tar -zcvf certification");
6098        if (eval("tar", "-C", "/", "-czf", "/tmp/cert.tgz", "etc/cert.pem", "etc/key.pem") == 0)
6099        {
6100        	flag_cert=1;
6101        }
6102	#endif
6103
6104        if(flag_cert==1)
6105        {
6106        	Cdbg(DBE, "nvram_setfile_https_crt_file");
6107
6108            if (nvram_setfile_https_crt_file("/tmp/cert.tgz", 8192)) {
6109            	Cdbg(DBE, "complete nvram_setfile_https_crt_file");
6110
6111				nvram_set_https_crt_save("1");
6112				nvram_set_value("https_intermediate_crt_save", "0");
6113                nvram_do_commit();
6114
6115				system("cat /etc/key.pem /etc/cert.pem > /etc/server.pem");
6116
6117                Cdbg(DBE, "end nvram_setfile_https_crt_file");
6118            }
6119
6120            unlink("/tmp/cert.tgz");
6121        }
6122
6123		//Cdbg(DBE, "restart webdav");
6124		//system("rc rc_service restart_webdav");
6125		Cdbg(DBE, "complete");
6126
6127	#endif
6128
6129		con->http_status = 200;
6130		con->file_finished = 1;
6131		return HANDLER_FINISHED;
6132	}
6133
6134	case HTTP_METHOD_SETROOTCERTIFICATE:{
6135
6136#if EMBEDDED_EANBLE
6137		if(!con->srv_socket->is_ssl){
6138			con->http_status = 403;
6139			return HANDLER_FINISHED;
6140		}
6141#endif
6142
6143		/*
6144		chunkqueue *cq = con->request_content_queue;
6145		assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
6146		chunk *c = cq->first;
6147		int r = c->mem->size;
6148		Cdbg(DBE, "MEM_CHUNK %s", c->mem->ptr);
6149		*/
6150
6151		xmlChar *key_content = NULL;
6152		xmlChar *cert_content = NULL;
6153		xmlChar *intermediate_crt_content = NULL;
6154		int flag_cert=0;
6155		int ret = 0;
6156
6157#ifdef USE_PROPPATCH
6158		if (con->request.content_length) {
6159			xmlDocPtr xml;
6160
6161			if (1 == smbdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
6162				xmlNode *rootnode = xmlDocGetRootElement(xml);
6163
6164				assert(rootnode);
6165
6166				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "content")) {
6167					xmlNode *cmd;
6168
6169					req_props = calloc(1, sizeof(*req_props));
6170
6171					for (cmd = rootnode->children; cmd; cmd = cmd->next) {
6172						if (0 == xmlStrcmp(cmd->name, BAD_CAST "key")) {
6173							key_content = xmlNodeGetContent(cmd);
6174						}
6175						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "cert")) {
6176							cert_content = xmlNodeGetContent(cmd);
6177						}
6178						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "intermediate_crt")) {
6179							intermediate_crt_content = xmlNodeGetContent(cmd);
6180						}
6181					}
6182				}
6183
6184			}
6185		}
6186#endif
6187
6188		if(key_content==NULL||cert_content==NULL){
6189			con->http_status = 400;
6190			return HANDLER_FINISHED;
6191		}
6192
6193		Cdbg(DBE, "key=%s, cert=%s", key_content, cert_content);
6194
6195		SSL_load_error_strings();
6196		SSLeay_add_ssl_algorithms();
6197
6198		SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_server_method()); // SSLv23 for IE
6199		if (!ssl_ctx) {
6200			con->http_status = 403;
6201			con->file_finished = 1;
6202			return HANDLER_FINISHED;
6203		}
6204		SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
6205		////////////////////////////////////////////////////////////////////////////////////////
6206
6207		buffer* command = buffer_init();
6208
6209		//- write cert
6210		buffer_copy_string(command, "echo \"");
6211		buffer_append_string(command, cert_content);
6212		buffer_append_string(command, "\" > /etc/cert.pem.1");
6213
6214		ret = system(command->ptr);
6215
6216		if(ret < 0){
6217			buffer_free(command);
6218			Cdbg(DBE, "cmd: %s\t error: %s", command->ptr, strerror(errno));
6219			con->http_status = 400;
6220			con->file_finished = 1;
6221			return HANDLER_FINISHED;
6222		}
6223
6224		// Set the certificate to be used
6225		if (SSL_CTX_use_certificate_file(ssl_ctx, "/etc/cert.pem.1", SSL_FILETYPE_PEM) <= 0) {
6226			SSL_CTX_free(ssl_ctx);
6227			ssl_ctx = NULL;
6228			con->http_status = 403;
6229			con->file_finished = 1;
6230			return HANDLER_FINISHED;
6231		}
6232		////////////////////////////////////////////////////////////////////////////////////////
6233
6234		//- write key
6235		buffer_copy_string(command, "echo \"");
6236		buffer_append_string(command, key_content);
6237		buffer_append_string(command, "\" > /etc/key.pem.1");
6238
6239		ret = system(command->ptr);
6240
6241		if(ret < 0){
6242			buffer_free(command);
6243			Cdbg(DBE, "cmd: %s\t error: %s", command->ptr, strerror(errno));
6244			con->http_status = 400;
6245			con->file_finished = 1;
6246			return HANDLER_FINISHED;
6247		}
6248
6249		// Indicate the key file to be used
6250		if (SSL_CTX_use_PrivateKey_file(ssl_ctx, "/etc/key.pem.1", SSL_FILETYPE_PEM) <= 0) {
6251			SSL_CTX_free(ssl_ctx);
6252			ssl_ctx = NULL;
6253			con->http_status = 403;
6254			con->file_finished = 1;
6255			return HANDLER_FINISHED;
6256		}
6257
6258		// Make sure the key and certificate file match
6259		if (!SSL_CTX_check_private_key(ssl_ctx)) {
6260			SSL_CTX_free(ssl_ctx);
6261			ssl_ctx = NULL;
6262			con->http_status = 403;
6263			con->file_finished = 1;
6264			return HANDLER_FINISHED;
6265		}
6266		////////////////////////////////////////////////////////////////////////////////////////
6267
6268		//- write intermediate cert
6269		unlink("/etc/intermediate_cert.pem.1");
6270
6271		int has_intermediate_crt_content = 0;
6272		if(intermediate_crt_content!=NULL && *intermediate_crt_content!='\0'){
6273			Cdbg(DBE, "intermediate_crt_content=%s", intermediate_crt_content);
6274
6275			buffer_copy_string(command, "echo \"");
6276			buffer_append_string(command, intermediate_crt_content);
6277			buffer_append_string(command, "\" > /etc/intermediate_cert.pem.1");
6278
6279			ret = system(command->ptr);
6280
6281			if(ret < 0){
6282				buffer_free(command);
6283				Cdbg(DBE, "cmd: %s\t error: %s", command->ptr, strerror(errno));
6284				con->http_status = 400;
6285				con->file_finished = 1;
6286				return HANDLER_FINISHED;
6287			}
6288
6289			// Set the intermediate certificate to be used
6290			if (SSL_CTX_use_certificate_chain_file(ssl_ctx, "/etc/intermediate_cert.pem.1") <= 0) {
6291				SSL_CTX_free(ssl_ctx);
6292				ssl_ctx = NULL;
6293				con->http_status = 403;
6294				con->file_finished = 1;
6295				return HANDLER_FINISHED;
6296			}
6297
6298			has_intermediate_crt_content = 1;
6299
6300		}
6301
6302#if 0
6303		FILE *fp;
6304		char line[1024];
6305		fp = fopen("openssl x509 -noout -issuer -in /etc/server.pem", "r");
6306		if(fp != NULL){
6307
6308			while(fscanf(fp, "%s\n", line) != EOF){
6309				Cdbg(DBE, "%s", line);
6310
6311				if( strncmp( line, "Subject:", 8 ) == 0 ){
6312					Cdbg(DBE, "1 Got it : %s", line);
6313				}
6314				else if( strncmp( line, "Issuer:", 7 ) == 0 ){
6315					Cdbg(DBE, "2 Got it : %s", line);
6316				}
6317			}
6318
6319			fclose(fp);
6320		}
6321#endif
6322
6323		if(ssl_ctx){
6324			SSL_CTX_free(ssl_ctx);
6325			ssl_ctx = NULL;
6326		}
6327		////////////////////////////////////////////////////////////////////////////////////////
6328
6329		Cdbg(DBE, "tar -zcvf certification");
6330
6331		if(rename("/etc/cert.pem.1", "/etc/cert.pem")!=0){
6332			con->http_status = 400;
6333			con->file_finished = 1;
6334			return HANDLER_FINISHED;
6335		}
6336
6337		if(rename("/etc/key.pem.1", "/etc/key.pem")!=0){
6338			con->http_status = 400;
6339			con->file_finished = 1;
6340			return HANDLER_FINISHED;
6341		}
6342
6343		if(has_intermediate_crt_content==1){
6344			if(rename("/etc/intermediate_cert.pem.1", "/etc/intermediate_cert.pem")!=0){
6345				con->http_status = 400;
6346				con->file_finished = 1;
6347				return HANDLER_FINISHED;
6348			}
6349		}
6350
6351#if EMBEDDED_EANBLE
6352
6353        if( ( has_intermediate_crt_content==1 && eval("tar", "-C", "/", "-czf", "/tmp/cert.tgz", "etc/cert.pem", "etc/key.pem", "etc/intermediate_cert.pem") == 0 ) ||
6354			( has_intermediate_crt_content==0 && eval("tar", "-C", "/", "-czf", "/tmp/cert.tgz", "etc/cert.pem", "etc/key.pem") == 0 ) )
6355        {
6356        	Cdbg(DBE, "nvram_setfile_https_crt_file");
6357
6358            if (nvram_setfile_https_crt_file("/tmp/cert.tgz", 8192)) {
6359            	Cdbg(DBE, "complete nvram_setfile_https_crt_file");
6360
6361				nvram_set_https_crt_save("1");
6362				nvram_set_value("https_intermediate_crt_save", has_intermediate_crt_content ? "1" : "0");
6363                nvram_do_commit();
6364
6365				system("cat /etc/key.pem /etc/cert.pem > /etc/server.pem");
6366
6367                Cdbg(DBE, "end nvram_setfile_https_crt_file");
6368            }
6369
6370            unlink("/tmp/cert.tgz");
6371
6372			con->http_status = 200;
6373			con->file_finished = 1;
6374        }
6375		else{
6376			con->http_status = 400;
6377			con->file_finished = 1;
6378		}
6379#else
6380		con->http_status = 200;
6381		con->file_finished = 1;
6382#endif
6383
6384		return HANDLER_FINISHED;
6385	}
6386
6387	case HTTP_METHOD_GETX509CERTINFO:{
6388
6389#if EMBEDDED_EANBLE
6390		if(!con->srv_socket->is_ssl){
6391			con->http_status = 403;
6392			return HANDLER_FINISHED;
6393		}
6394#endif
6395		char issuer_name[1024];
6396		char subject_name[1024];
6397		char crt_start_date[50];
6398		char crt_end_date[50];
6399
6400		X509 *x509data = NULL;
6401		FILE* fp = fopen("/etc/server.pem", "r");
6402		if(fp!=NULL){
6403			PEM_read_X509(fp, &x509data, NULL, NULL);
6404			fclose(fp);
6405
6406			if (x509data != NULL) {
6407
6408				X509_NAME_oneline(X509_get_issuer_name(x509data), issuer_name, sizeof(issuer_name));
6409				X509_NAME_oneline(X509_get_subject_name(x509data), subject_name, sizeof(subject_name));
6410
6411				strcpy(crt_start_date, x509data->cert_info->validity->notBefore->data);
6412				strcpy(crt_end_date, x509data->cert_info->validity->notAfter->data);
6413
6414				Cdbg(DBE, "Issuer  name: %s", issuer_name);
6415			}
6416		}
6417
6418		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
6419
6420		b = buffer_init();
6421
6422		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
6423		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
6424
6425		buffer_append_string_len(b, CONST_STR_LEN("<issuer>"));
6426		buffer_append_string(b, issuer_name);
6427		buffer_append_string_len(b, CONST_STR_LEN("</issuer>"));
6428
6429		buffer_append_string_len(b, CONST_STR_LEN("<subject>"));
6430		buffer_append_string(b, subject_name);
6431		buffer_append_string_len(b, CONST_STR_LEN("</subject>"));
6432
6433		buffer_append_string_len(b, CONST_STR_LEN("<crt_start_date>"));
6434		buffer_append_string(b, crt_start_date);
6435		buffer_append_string_len(b, CONST_STR_LEN("</crt_start_date>"));
6436
6437		buffer_append_string_len(b, CONST_STR_LEN("<crt_end_date>"));
6438		buffer_append_string(b, crt_end_date);
6439		buffer_append_string_len(b, CONST_STR_LEN("</crt_end_date>"));
6440
6441		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
6442
6443		chunkqueue_append_buffer(con->write_queue, b);
6444		buffer_free(b);
6445
6446		con->http_status = 200;
6447		con->file_finished = 1;
6448
6449		return HANDLER_FINISHED;
6450	}
6451
6452	case HTTP_METHOD_APPLYAPP:{
6453
6454		if(!con->srv_socket->is_ssl){
6455			con->http_status = 403;
6456			return HANDLER_FINISHED;
6457		}
6458
6459		buffer* action_mode = NULL;
6460		buffer* rc_service = NULL;
6461		buffer* set_nvram_value = NULL;
6462
6463		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "ACTION_MODE"))) {
6464			action_mode = ds->value;
6465		} else {
6466			con->http_status = 400;
6467			return HANDLER_FINISHED;
6468		}
6469
6470		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "SET_NVRAM"))) {
6471			set_nvram_value = ds->value;
6472		}
6473
6474		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "RC_SERVICE"))) {
6475			rc_service = ds->value;
6476		}
6477
6478		if(buffer_is_equal_string(action_mode, CONST_STR_LEN("apply"))){
6479
6480			//- set nvram(ex. wl_bss_enabled=1;wl_unit=0;wl_subunit=1)
6481			if(!buffer_is_empty(set_nvram_value)){
6482				char *pch, *pch2, *saveptr=NULL, *saveptr2=NULL;
6483				pch = strtok_r(set_nvram_value->ptr, ";", &saveptr);
6484				int b_nvram_is_set = 0;
6485
6486				while(pch!=NULL){
6487					char* key_value = strdup(pch);
6488					pch2 = strtok_r(key_value, "=", &saveptr2);
6489
6490					while(pch2!=NULL){
6491						buffer* buffer_key = buffer_init();
6492						buffer* buffer_value = buffer_init();
6493
6494						//- key
6495						if(pch2)
6496							buffer_copy_string(buffer_key, pch2);
6497
6498						//- value
6499						pch2 = strtok_r(NULL, "=", &saveptr2);
6500						if(pch2)
6501							buffer_copy_string(buffer_value, pch2);
6502
6503						if(!buffer_is_empty(buffer_key)&&!buffer_is_empty(buffer_value)){
6504
6505						#if EMBEDDED_EANBLE
6506							nvram_set_value(buffer_key->ptr, buffer_value->ptr);
6507						#endif
6508
6509							Cdbg(DBE, "set nvram: key=%s, value=%s", buffer_key->ptr, buffer_value->ptr);
6510
6511							b_nvram_is_set = 1;
6512						}
6513
6514						buffer_free(buffer_key);
6515						buffer_free(buffer_value);
6516
6517						//- Next
6518						pch2 = strtok_r(NULL, "=", &saveptr2);
6519					}
6520
6521					if(key_value)
6522						free(key_value);
6523
6524					//- Next
6525					pch = strtok_r(NULL, ";", &saveptr);
6526				}
6527
6528				if(b_nvram_is_set==1){
6529				#if EMBEDDED_EANBLE
6530					nvram_do_commit();
6531				#endif
6532				}
6533			}
6534
6535			//- run rc_service
6536			if(!buffer_is_empty(rc_service)){
6537				char *pch;
6538				pch = strtok(rc_service->ptr, ";");
6539
6540				while(pch!=NULL){
6541
6542					buffer* rc_command = buffer_init();
6543					#ifdef USE_TCAPI
6544					buffer_copy_string(rc_command, "service ");
6545					#else
6546					buffer_copy_string(rc_command, "rc rc_service ");
6547					#endif
6548					buffer_append_string(rc_command, pch);
6549
6550					Cdbg(DBE, "rc_command: %s", rc_command->ptr);
6551					int ret = system(rc_command->ptr);
6552
6553					if(ret < 0){
6554						buffer_free(rc_command);
6555						Cdbg(DBE, "cmd: %s\t error: %s", rc_command->ptr, strerror(errno));
6556						con->http_status = 400;
6557						con->file_finished = 1;
6558						return HANDLER_FINISHED;
6559
6560						break;
6561					}
6562
6563					buffer_free(rc_command);
6564
6565					//- Next
6566					pch = strtok(NULL, ";");
6567				}
6568			}
6569		}
6570
6571		con->http_status = 200;
6572		con->file_finished = 1;
6573		return HANDLER_FINISHED;
6574	}
6575
6576	case HTTP_METHOD_NVRAMGET:{
6577		if(!con->srv_socket->is_ssl){
6578			con->http_status = 403;
6579			return HANDLER_FINISHED;
6580		}
6581
6582		buffer* key = NULL;
6583
6584		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "KEY"))) {
6585			key = ds->value;
6586		} else {
6587			con->http_status = 400;
6588			return HANDLER_FINISHED;
6589		}
6590
6591		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
6592
6593		b = buffer_init();
6594
6595		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
6596		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
6597
6598		if(!buffer_is_empty(key)){
6599			char *pch;
6600			pch = strtok(key->ptr, ";");
6601
6602			while(pch!=NULL){
6603				char* value = NULL;
6604
6605				#if EMBEDDED_EANBLE
6606				value = nvram_get_value(pch);
6607				#endif
6608
6609				if(value){
6610					buffer_append_string_len(b,CONST_STR_LEN("<nvram key=\""));
6611					buffer_append_string(b,pch);
6612					buffer_append_string_len(b,CONST_STR_LEN("\" value=\""));
6613					buffer_append_string(b,value);
6614					buffer_append_string_len(b,CONST_STR_LEN("\"/>"));
6615				}
6616
6617				//- Next
6618				pch = strtok(NULL, ";");
6619			}
6620		}
6621
6622		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
6623
6624		chunkqueue_append_buffer(con->write_queue, b);
6625		buffer_free(b);
6626
6627		con->http_status = 200;
6628		con->file_finished = 1;
6629		return HANDLER_FINISHED;
6630	}
6631
6632	case HTTP_METHOD_UPLOADTOFACEBOOK:{
6633		Cdbg(1, "do HTTP_METHOD_UPLOADTOFACEBOOK");
6634#if EMBEDDED_EANBLE
6635		if(!con->srv_socket->is_ssl){
6636			con->http_status = 403;
6637			return HANDLER_FINISHED;
6638		}
6639#endif
6640
6641		buffer* filename = NULL;
6642		buffer* title = NULL;
6643		buffer* album = NULL;
6644		buffer* auth_token = NULL;
6645
6646		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "FILENAME"))) {
6647			filename = ds->value;
6648			buffer_urldecode_path(filename);
6649		} else {
6650			con->http_status = 400;
6651			return HANDLER_FINISHED;
6652		}
6653
6654		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TITLE"))) {
6655			title = ds->value;
6656			buffer_urldecode_path(title);
6657		} else {
6658			con->http_status = 400;
6659			return HANDLER_FINISHED;
6660		}
6661
6662		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
6663			auth_token = ds->value;
6664		} else {
6665			con->http_status = 400;
6666			return HANDLER_FINISHED;
6667		}
6668
6669		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "ALBUM"))) {
6670			album = ds->value;
6671		} else {
6672			con->http_status = 400;
6673			return HANDLER_FINISHED;
6674		}
6675
6676		CURL *curl;
6677		CURLcode rt;
6678		struct curl_httppost *formpost = NULL;
6679		struct curl_httppost *lastptr = NULL;
6680		char md5[129];
6681		char* response_str;
6682		char url_upload_facebook[1024] = "\0";
6683		curl = curl_easy_init();
6684
6685		strcpy(url_upload_facebook, "https://graph.facebook.com/");
6686		strcat(url_upload_facebook, album->ptr);
6687		strcat(url_upload_facebook, "/photos");
6688
6689		Cdbg(1, "url_upload_facebook=%s", url_upload_facebook);
6690
6691		if(curl) {
6692			Cdbg(1, "curl_easy_init OK");
6693
6694			/* Set Host to target in HTTP header, and set response handler
6695		 	* function */
6696			curl_easy_setopt(curl, CURLOPT_URL, url_upload_facebook);
6697
6698
6699			/* Build the form post */
6700			curl_formadd(&formpost, &lastptr,
6701			             CURLFORM_COPYNAME, "access_token",
6702			             CURLFORM_COPYCONTENTS, auth_token->ptr, CURLFORM_END);
6703
6704			curl_formadd(&formpost, &lastptr,
6705			             CURLFORM_COPYNAME, "message",
6706			             CURLFORM_COPYCONTENTS, title->ptr, CURLFORM_END);
6707
6708			curl_formadd(&formpost, &lastptr,
6709			             CURLFORM_COPYNAME, "status",
6710			             CURLFORM_COPYCONTENTS, "success", CURLFORM_END);
6711
6712			char photo_path[1024] = "\0";
6713			sprintf(photo_path, "%s/%s", "/tmp", filename->ptr);
6714
6715			char photo_src_path[1024] = "\0";
6716			sprintf(photo_src_path, "%s/%s", con->url.path->ptr, filename->ptr);
6717
6718			int status = 0, ret, src_fd = -1;
6719			FILE* dst_fd;
6720
6721			if (-1 == (dst_fd = fopen(photo_path, "wb"))) {
6722				/* opening the destination failed for some reason */
6723				switch(errno) {
6724				case EEXIST:
6725					status = 412;
6726					break;
6727				case EISDIR:
6728					status = 409;
6729					break;
6730				case ENOENT:
6731					/* at least one part in the middle wasn't existing */
6732					status = 409;
6733					break;
6734				default:
6735					status = 403;
6736					break;
6737				}
6738				fclose(dst_fd);
6739
6740				con->http_status = status;
6741				return HANDLER_FINISHED;
6742			}
6743
6744			char buff[2048];
6745			if (src_fd = smbc_open(photo_src_path, O_RDONLY, WEBDAV_FILE_MODE)) {
6746				do {
6747					ret = smbc_read(src_fd, buff, sizeof(buff));
6748					if (ret > 0) {
6749						if (-1 == fwrite(buff, sizeof(char), sizeof(buff), dst_fd)) {
6750							switch(errno) {
6751							case ENOSPC:
6752								status = 507;
6753								break;
6754							default:
6755								status = 403;
6756								break;
6757							}
6758
6759							smbc_close(src_fd);
6760							fclose(dst_fd);
6761							unlink(photo_path);
6762
6763							con->http_status = status;
6764							return HANDLER_FINISHED;
6765						}
6766					}
6767				} while (ret > 0);
6768			}
6769
6770			smbc_close(src_fd);
6771			fclose(dst_fd);
6772
6773			Cdbg(DBE, "complete copy file %s -> %s", photo_src_path, photo_path);
6774
6775			curl_formadd(&formpost, &lastptr,
6776			             CURLFORM_COPYNAME, "source",
6777			             CURLFORM_FILE, photo_path, CURLFORM_END);
6778
6779			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
6780			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
6781
6782			curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
6783			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_func);
6784			curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_str);
6785
6786			Cdbg(1, "Uploading...");
6787			rt = curl_easy_perform(curl);
6788
6789			#if 1
6790			/* now extract transfer info */
6791			double speed_upload, total_time;
6792      		curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
6793      		curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
6794
6795      		Cdbg(1, "Speed: %.3f bytes/sec during %.3f seconds, response_str=%s",
6796              		speed_upload, total_time, response_str);
6797
6798			free(response_str);
6799			#else
6800			if (rt) {
6801				Cdbg(1, "An error occurred during upload! %s", curl_easy_strerror(rt));
6802			}
6803			else{
6804				/* now extract transfer info */
6805				double speed_upload, total_time;
6806      			curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
6807      			curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
6808
6809      			Cdbg(1, "Speed: %.3f bytes/sec during %.3f seconds",
6810              		speed_upload, total_time);
6811			}
6812			#endif
6813
6814			/* Done. Cleanup. */
6815			curl_easy_cleanup(curl);
6816			curl_formfree(formpost);
6817
6818			unlink(photo_path);
6819		}
6820
6821		con->http_status = 200;
6822		con->file_finished = 1;
6823		return HANDLER_FINISHED;
6824	}
6825
6826	case HTTP_METHOD_UPLOADTOPICASA:{
6827		Cdbg(DBE, "do HTTP_METHOD_UPLOADTOPICASA");
6828#if EMBEDDED_EANBLE
6829		if(!con->srv_socket->is_ssl){
6830			con->http_status = 403;
6831			return HANDLER_FINISHED;
6832		}
6833#endif
6834
6835		buffer* filename = NULL;
6836		buffer* title = NULL;
6837		buffer* auth_token = NULL;
6838		buffer* user_id = NULL;
6839		buffer* album_id = NULL;
6840		long response_result = 0;
6841
6842		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "FILENAME"))) {
6843			filename = ds->value;
6844			buffer_urldecode_path(filename);
6845		} else {
6846			con->http_status = 400;
6847			return HANDLER_FINISHED;
6848		}
6849
6850		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TITLE"))) {
6851			title = ds->value;
6852			buffer_urldecode_path(title);
6853		} else {
6854			con->http_status = 400;
6855			return HANDLER_FINISHED;
6856		}
6857
6858		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "UID"))) {
6859			user_id = ds->value;
6860		} else {
6861			con->http_status = 400;
6862			return HANDLER_FINISHED;
6863		}
6864
6865		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "AID"))) {
6866			album_id = ds->value;
6867		} else {
6868			con->http_status = 400;
6869			return HANDLER_FINISHED;
6870		}
6871
6872		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
6873			auth_token = ds->value;
6874		} else {
6875			con->http_status = 400;
6876			return HANDLER_FINISHED;
6877		}
6878
6879		CURL *curl;
6880		CURLcode rt;
6881
6882		#if 0
6883		_buffer_t upload_response;
6884		#endif
6885
6886		buffer* buffer_photoid;
6887
6888		curl = curl_easy_init();
6889		if(curl) {
6890			Cdbg(DBE, "curl_easy_init OK");
6891
6892			char request_url[1024] = "\0";
6893			sprintf(request_url, "https://picasaweb.google.com/data/feed/api/user/%s/albumid/%s", user_id->ptr, album_id->ptr);
6894			curl_easy_setopt(curl, CURLOPT_URL, request_url);
6895
6896		#if 1
6897			char photo_path[1024] = "\0";
6898			sprintf(photo_path, "/tmp/%s", filename->ptr);
6899			Cdbg(1, "photo_path=%s", photo_path);
6900
6901			char photo_src_path[1024] = "\0";
6902			sprintf(photo_src_path, "%s/%s", con->url.path->ptr, filename->ptr);
6903
6904			int status = 0, ret, src_fd = -1;
6905			FILE* dst_fd;
6906
6907			if (-1 == (dst_fd = fopen(photo_path, "wb"))) {
6908				/* opening the destination failed for some reason */
6909				switch(errno) {
6910				case EEXIST:
6911					status = 412;
6912					break;
6913				case EISDIR:
6914					status = 409;
6915					break;
6916				case ENOENT:
6917					/* at least one part in the middle wasn't existing */
6918					status = 409;
6919					break;
6920				default:
6921					status = 403;
6922					break;
6923				}
6924				fclose(dst_fd);
6925
6926				con->http_status = status;
6927				return HANDLER_FINISHED;
6928			}
6929
6930			char buff[2048];
6931			if (src_fd = smbc_open(photo_src_path, O_RDONLY, WEBDAV_FILE_MODE)) {
6932				do {
6933					ret = smbc_read(src_fd, buff, sizeof(buff));
6934					if (ret > 0) {
6935						if (-1 == fwrite(buff, sizeof(char), sizeof(buff), dst_fd)) {
6936							switch(errno) {
6937							case ENOSPC:
6938								status = 507;
6939								break;
6940							default:
6941								status = 403;
6942								break;
6943							}
6944
6945							smbc_close(src_fd);
6946							fclose(dst_fd);
6947							unlink(photo_path);
6948
6949							con->http_status = status;
6950							return HANDLER_FINISHED;
6951						}
6952					}
6953				} while (ret > 0);
6954			}
6955
6956			smbc_close(src_fd);
6957			fclose(dst_fd);
6958
6959			FILE *fd;
6960 			fd = fopen(photo_path, "rb"); /* open file to upload */
6961		  	if(!fd) {
6962				curl_easy_cleanup(curl);
6963				unlink(photo_path);
6964		    	con->http_status = 404;
6965				return HANDLER_FINISHED;
6966		 	}
6967
6968			/* to get the file size */
6969			struct stat file_info;
6970  			if(fstat(fileno(fd), &file_info) != 0) {
6971				fclose(fd);
6972				unlink(photo_path);
6973				curl_easy_cleanup(curl);
6974		    	con->http_status = 404;
6975				return HANDLER_FINISHED;
6976			}
6977
6978			long file_size = file_info.st_size;
6979			char* file_data = (char*) malloc (sizeof(char)*file_size);
6980  			if(file_data == NULL) {
6981				fclose(fd);
6982				unlink(photo_path);
6983				curl_easy_cleanup(curl);
6984		    	con->http_status = 400;
6985				return HANDLER_FINISHED;
6986			}
6987
6988  			// copy the file into the buffer:
6989		  	size_t result = fread( file_data, 1, file_size, fd );
6990			if (result != file_size) {
6991				free(file_data);
6992				fclose(fd);
6993				unlink(photo_path);
6994				curl_easy_cleanup(curl);
6995		    	con->http_status = 400;
6996				return HANDLER_FINISHED;
6997			}
6998
6999			unlink(photo_path);
7000		#else
7001			char photo_path[1024] = "\0";
7002			sprintf(photo_path, "%s/%s", con->url.path->ptr, filename->ptr);
7003
7004			int *fd;
7005			struct stat st;
7006
7007			Cdbg(1, "open %s", photo_path);
7008 			fd = smbc_open(photo_path, O_RDONLY, WEBDAV_FILE_MODE); /* open file to upload */
7009		  	if(!fd) {
7010				curl_easy_cleanup(curl);
7011		    	con->http_status = 404;
7012				return HANDLER_FINISHED;
7013		 	}
7014
7015			/* to get the file size */
7016  			if (-1 == smbc_wrapper_stat(con, con->url.path->ptr, &st)) {
7017				smbc_close(fd);
7018				curl_easy_cleanup(curl);
7019		    	con->http_status = 404;
7020				return HANDLER_FINISHED;
7021			}
7022
7023			long file_size = st.st_size;
7024			//Cdbg(1, "file_size %ld", file_size);
7025			char* file_data = (char*) malloc (sizeof(char)*file_size);
7026  			if(file_data == NULL) {
7027				smbc_close(fd);
7028				curl_easy_cleanup(curl);
7029		    	con->http_status = 400;
7030				return HANDLER_FINISHED;
7031			}
7032
7033			// copy the file into the buffer:
7034		  	size_t result = smbc_read(fd, file_data, file_size);
7035
7036			if (result != file_size) {
7037				free(file_data);
7038				smbc_close(fd);
7039				curl_easy_cleanup(curl);
7040		    	con->http_status = 400;
7041				return HANDLER_FINISHED;
7042			}
7043
7044			Cdbg(1, "complete");
7045
7046		#endif
7047
7048			char mpart1[4096] = "\0";
7049  			sprintf(mpart1, "\nMedia multipart posting\n"
7050				"--END_OF_PART\n"
7051				"Content-Type: application/atom+xml\n\n"
7052				"<entry xmlns='http://www.w3.org/2005/Atom'>\n"
7053				"<title>%s</title>\n"
7054                "<summary></summary>\n"
7055                "<category scheme=\"http://schemas.google.com/g/2005#kind\"\n"
7056                " term=\"http://schemas.google.com/photos/2007#photo\"/>"
7057				"</entry>\n"
7058				"--END_OF_PART\n"
7059				"Content-Type: image/jpeg\n\n", title->ptr);
7060
7061			long mpart1size = strlen(mpart1);
7062			long postdata_length = mpart1size + file_size + strlen("\n--END_OF_PART--");
7063  			char *postdata = (char*)malloc(sizeof(char)*postdata_length);
7064
7065			if(postdata == NULL) {
7066				free(file_data);
7067				fclose(fd);
7068				curl_easy_cleanup(curl);
7069		    	con->http_status = 400;
7070				return HANDLER_FINISHED;
7071			}
7072
7073			memcpy( postdata, mpart1, mpart1size);
7074			memcpy( postdata + mpart1size, file_data, file_size);
7075			memcpy( postdata + mpart1size + file_size, "\n--END_OF_PART--", strlen("\n--END_OF_PART--") );
7076
7077			free(file_data);
7078			fclose(fd);
7079
7080			struct curl_slist *headers = NULL;
7081			headers = curl_slist_append(headers,"Content-Type: multipart/related; boundary=\"END_OF_PART\"");
7082			headers = curl_slist_append(headers,"MIME-version: 1.0");
7083			headers = curl_slist_append(headers,"Expect:");
7084			headers = curl_slist_append(headers,"GData-Version: 2");
7085
7086			char authHeader[1024] = "\0";
7087			sprintf(authHeader, "Authorization: OAuth %s", auth_token->ptr);
7088			headers = curl_slist_append(headers, authHeader);
7089
7090			char content_length[1024] = "\0";
7091			sprintf(content_length, "Content-Length=%d", file_size);
7092			headers = curl_slist_append(headers, content_length);
7093
7094			curl_easy_setopt(curl, CURLOPT_VERBOSE, 2);
7095			curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
7096			curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
7097			curl_easy_setopt(curl, CURLOPT_POST, 1);
7098			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
7099
7100			curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
7101  			curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postdata_length);
7102
7103			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
7104			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
7105
7106			Cdbg(DBE, "Uploading...");
7107			rt = curl_easy_perform(curl);
7108
7109			curl_slist_free_all(headers);
7110
7111			curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_result);
7112
7113			/* Done. Cleanup. */
7114			free(postdata);
7115
7116			curl_easy_cleanup(curl);
7117		}
7118
7119		con->http_status = ( response_result == 201 ) ? 200 : 501;
7120		con->file_finished = 1;
7121		return HANDLER_FINISHED;
7122	}
7123
7124	case HTTP_METHOD_UPLOADTOFLICKR:{
7125		Cdbg(1, "do HTTP_METHOD_UPLOADTOFLICKR");
7126
7127#if EMBEDDED_EANBLE
7128		if(!con->srv_socket->is_ssl){
7129			con->http_status = 403;
7130			return HANDLER_FINISHED;
7131		}
7132#endif
7133
7134		buffer* filename = NULL;
7135		buffer* title = NULL;
7136		buffer* auth_token = NULL;
7137
7138		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "FILENAME"))) {
7139			filename = ds->value;
7140			buffer_urldecode_path(filename);
7141		} else {
7142			con->http_status = 400;
7143			return HANDLER_FINISHED;
7144		}
7145
7146		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TITLE"))) {
7147			title = ds->value;
7148			buffer_urldecode_path(title);
7149		} else {
7150			con->http_status = 400;
7151			return HANDLER_FINISHED;
7152		}
7153
7154		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
7155			auth_token = ds->value;
7156		} else {
7157			con->http_status = 400;
7158			return HANDLER_FINISHED;
7159		}
7160
7161		//char api_key[100] = "37140360286c5cd9952023fa8b662a64";
7162		//char secret[100] = "804b51d14d840d6e";
7163		char api_key[100] = "c0466d7736e0275d062ce64aefaacfe0";
7164		char secret[100] = "228e160cf8805246";
7165		CURL *curl;
7166		CURLcode rt;
7167		struct curl_httppost *formpost = NULL;
7168		struct curl_httppost *lastptr = NULL;
7169		char md5[129];
7170		char* response_str;
7171		buffer* buffer_photoid = buffer_init();
7172
7173		curl = curl_easy_init();
7174		if(curl) {
7175			Cdbg(DBE, "curl_easy_init OK");
7176
7177			/* Set Host to target in HTTP header, and set response handler
7178			* function */
7179			curl_easy_setopt(curl, CURLOPT_URL, "https://api.flickr.com/services/upload/");
7180			/* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); */
7181
7182			md5sum(md5, 7, secret, "api_key", api_key, "auth_token", auth_token->ptr, "title", title->ptr);
7183			Cdbg(DBE, "md5=%s", md5);
7184
7185			/* Build the form post */
7186			curl_formadd(&formpost, &lastptr,
7187						 CURLFORM_COPYNAME, "api_key",
7188						 CURLFORM_COPYCONTENTS, api_key, CURLFORM_END);
7189
7190			curl_formadd(&formpost, &lastptr,
7191						 CURLFORM_COPYNAME, "auth_token",
7192						 CURLFORM_COPYCONTENTS, auth_token->ptr, CURLFORM_END);
7193
7194			curl_formadd(&formpost, &lastptr,
7195						 CURLFORM_COPYNAME, "api_sig",
7196						 CURLFORM_COPYCONTENTS, md5, CURLFORM_END);
7197
7198			curl_formadd(&formpost, &lastptr,
7199						 CURLFORM_COPYNAME, "title",
7200						 CURLFORM_COPYCONTENTS, title->ptr, CURLFORM_END);
7201
7202			char photo_path[1024] = "\0";
7203			sprintf(photo_path, "/tmp/%s", filename->ptr);
7204			Cdbg(1, "photo_path=%s", photo_path);
7205
7206			char photo_src_path[1024] = "\0";
7207			sprintf(photo_src_path, "%s/%s", con->url.path->ptr, filename->ptr);
7208
7209			int status = 0, ret, src_fd = -1;
7210			FILE* dst_fd;
7211
7212			if (-1 == (dst_fd = fopen(photo_path, "wb"))) {
7213				/* opening the destination failed for some reason */
7214				switch(errno) {
7215				case EEXIST:
7216					status = 412;
7217					break;
7218				case EISDIR:
7219					status = 409;
7220					break;
7221				case ENOENT:
7222					/* at least one part in the middle wasn't existing */
7223					status = 409;
7224					break;
7225				default:
7226					status = 403;
7227					break;
7228				}
7229				fclose(dst_fd);
7230
7231				con->http_status = status;
7232				return HANDLER_FINISHED;
7233			}
7234
7235			char buff[2048];
7236			if (src_fd = smbc_open(photo_src_path, O_RDONLY, WEBDAV_FILE_MODE)) {
7237				do {
7238					ret = smbc_read(src_fd, buff, sizeof(buff));
7239					if (ret > 0) {
7240						if (-1 == fwrite(buff, sizeof(char), sizeof(buff), dst_fd)) {
7241							switch(errno) {
7242							case ENOSPC:
7243								status = 507;
7244								break;
7245							default:
7246								status = 403;
7247								break;
7248							}
7249
7250							smbc_close(src_fd);
7251							fclose(dst_fd);
7252							unlink(photo_path);
7253
7254							con->http_status = status;
7255							return HANDLER_FINISHED;
7256						}
7257					}
7258				} while (ret > 0);
7259			}
7260
7261			smbc_close(src_fd);
7262			fclose(dst_fd);
7263
7264			Cdbg(DBE, "complete copy file %s -> %s", photo_src_path, photo_path);
7265
7266			curl_formadd(&formpost, &lastptr,
7267						 CURLFORM_COPYNAME, "photo",
7268						 CURLFORM_FILE, photo_path, CURLFORM_END);
7269
7270			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
7271			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
7272
7273			curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
7274			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_func);
7275			curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_str);
7276
7277			Cdbg(1, "Uploading...");
7278			rt = curl_easy_perform(curl);
7279
7280			xmlDocPtr xml = xmlParseMemory(response_str, strlen(response_str));
7281			if(xml){
7282				xmlNode *rootnode = xmlDocGetRootElement(xml);
7283
7284				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "rsp")) {
7285
7286					xmlChar *stat = xmlGetProp(rootnode,(const xmlChar*) "stat");
7287
7288					if (0 == xmlStrcmp(stat, BAD_CAST "ok")) {
7289
7290						xmlNode *childnode;
7291						for (childnode = rootnode->children; childnode; childnode = childnode->next) {
7292							if (0 == xmlStrcmp(childnode->name, BAD_CAST "photoid")) {
7293								xmlChar *photoid = xmlNodeGetContent(childnode);
7294								buffer_copy_string( buffer_photoid, photoid );
7295								break;
7296							}
7297						}
7298					}
7299				}
7300
7301				xmlFreeDoc(xml);
7302			}
7303
7304			free(response_str);
7305
7306			/* Done. Cleanup. */
7307			curl_easy_cleanup(curl);
7308			curl_formfree(formpost);
7309
7310			unlink(photo_path);
7311		}
7312
7313		if(!buffer_is_empty(buffer_photoid)){
7314
7315			Cdbg(1, "buffer_photoid=%s", buffer_photoid->ptr);
7316			response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
7317
7318			b = buffer_init();
7319
7320			buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
7321			buffer_append_string_len(b,CONST_STR_LEN("<result>"));
7322			buffer_append_string_len(b,CONST_STR_LEN("<photoid>"));
7323			buffer_append_string_buffer(b,buffer_photoid);
7324			buffer_append_string_len(b,CONST_STR_LEN("</photoid>"));
7325			buffer_append_string_len(b,CONST_STR_LEN("</result>"));
7326
7327			chunkqueue_append_buffer(con->write_queue, b);
7328			buffer_free(b);
7329
7330			con->http_status = 200;
7331		}
7332		else
7333			con->http_status = 501;
7334
7335		buffer_free(buffer_photoid);
7336
7337		con->file_finished = 1;
7338		return HANDLER_FINISHED;
7339	}
7340
7341	case HTTP_METHOD_UPLOADTOTWITTER:{
7342		Cdbg(DBE, "do HTTP_METHOD_UPLOADTOTWITTER");
7343
7344#if EMBEDDED_EANBLE
7345		if(!con->srv_socket->is_ssl){
7346			con->http_status = 403;
7347			return HANDLER_FINISHED;
7348		}
7349#endif
7350
7351		buffer* filename = NULL;
7352		buffer* title = NULL;
7353		buffer* auth_token = NULL;
7354		buffer* auth_secret = NULL;
7355		buffer* nonce = NULL;
7356		buffer* timestamp = NULL;
7357		buffer* signature = NULL;
7358		buffer* photo_size_limit = NULL;
7359
7360		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "FILENAME"))) {
7361			filename = ds->value;
7362			buffer_urldecode_path(filename);
7363		} else {
7364			con->http_status = 400;
7365			return HANDLER_FINISHED;
7366		}
7367
7368		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TITLE"))) {
7369			title = ds->value;
7370			buffer_urldecode_path(title);
7371		} else {
7372			con->http_status = 400;
7373			return HANDLER_FINISHED;
7374		}
7375
7376		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
7377			auth_token = ds->value;
7378		} else {
7379			con->http_status = 400;
7380			return HANDLER_FINISHED;
7381		}
7382
7383		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "SECRET"))) {
7384			auth_secret = ds->value;
7385		} else {
7386			con->http_status = 400;
7387			return HANDLER_FINISHED;
7388		}
7389
7390		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "NONCE"))) {
7391			nonce = ds->value;
7392		} else {
7393			con->http_status = 400;
7394			return HANDLER_FINISHED;
7395		}
7396
7397		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TIMESTAMP"))) {
7398			timestamp = ds->value;
7399		} else {
7400			con->http_status = 400;
7401			return HANDLER_FINISHED;
7402		}
7403
7404		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "SIGNATURE"))) {
7405			signature = ds->value;
7406		} else {
7407			con->http_status = 400;
7408			return HANDLER_FINISHED;
7409		}
7410
7411		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "PHOTOSIZELIMIT"))) {
7412			photo_size_limit = ds->value;
7413		} else {
7414			con->http_status = 400;
7415			return HANDLER_FINISHED;
7416		}
7417
7418		char consumer_key[100] = "hBQrdHdHClXylEI6by40DTMVA";
7419
7420		CURL *curl;
7421		CURLcode rt;
7422		struct curl_httppost *formpost = NULL;
7423		struct curl_httppost *lastptr = NULL;
7424		char* response_str = NULL;
7425		long response_code = 0;
7426
7427		curl = curl_easy_init();
7428		if(curl) {
7429			Cdbg(DBE, "curl_easy_init OK");
7430
7431			/* Set Host to target in HTTP header, and set response handler
7432		 	* function */
7433		 	//curl_easy_setopt(curl, CURLOPT_URL, "https://upload.twitter.com/1.1/statuses/update_with_media.json");
7434			curl_easy_setopt(curl, CURLOPT_URL, "https://api.twitter.com/1.1/statuses/update_with_media.json");
7435
7436			struct curl_slist *headers = NULL;
7437			char authHeader[1024] = "\0";
7438			sprintf(authHeader, "Authorization: OAuth"
7439				" oauth_consumer_key=\"%s\","
7440				" oauth_nonce=\"%s\","
7441				" oauth_signature_method=\"HMAC-SHA1\","
7442				" oauth_timestamp=\"%s\","
7443				" oauth_token=\"%s\","
7444				" oauth_version=\"1.0\","
7445				" oauth_signature=\"%s\"",
7446				consumer_key,
7447				nonce->ptr,
7448				timestamp->ptr,
7449				auth_token->ptr,
7450				signature->ptr);
7451			headers = curl_slist_append(headers, authHeader);
7452
7453			headers = curl_slist_append(headers,"Content-Type: multipart/form-data");
7454
7455			#if 0
7456			char photo_path[1024] = "\0";
7457			sprintf(photo_path, "%s/%s", con->physical.path->ptr, filename->ptr);
7458			Cdbg(DBE, "photo_path=%s", photo_path);
7459
7460			FILE *fd;
7461 			fd = fopen(photo_path, "rb"); /* open file to upload */
7462		  	if(!fd) {
7463				curl_easy_cleanup(curl);
7464		    	con->http_status = 404;
7465				return HANDLER_FINISHED;
7466		 	}
7467
7468			/* to get the file size */
7469			struct stat file_info;
7470  			if(fstat(fileno(fd), &file_info) != 0) {
7471				fclose(fd);
7472				curl_easy_cleanup(curl);
7473		    	con->http_status = 404;
7474				return HANDLER_FINISHED;
7475			}
7476			#else
7477			char photo_path[1024] = "\0";
7478			sprintf(photo_path, "/tmp/%s", filename->ptr);
7479
7480			char photo_src_path[1024] = "\0";
7481			sprintf(photo_src_path, "%s/%s", con->url.path->ptr, filename->ptr);
7482
7483			int status = 0, ret, src_fd = -1;
7484			FILE* dst_fd;
7485
7486			if (-1 == (dst_fd = fopen(photo_path, "wb"))) {
7487				/* opening the destination failed for some reason */
7488				switch(errno) {
7489				case EEXIST:
7490					status = 412;
7491					break;
7492				case EISDIR:
7493					status = 409;
7494					break;
7495				case ENOENT:
7496					/* at least one part in the middle wasn't existing */
7497					status = 409;
7498					break;
7499				default:
7500					status = 403;
7501					break;
7502				}
7503				fclose(dst_fd);
7504				curl_easy_cleanup(curl);
7505				con->http_status = status;
7506				return HANDLER_FINISHED;
7507			}
7508
7509			char buff[2048];
7510			if (src_fd = smbc_open(photo_src_path, O_RDONLY, WEBDAV_FILE_MODE)) {
7511				do {
7512					ret = smbc_read(src_fd, buff, sizeof(buff));
7513					if (ret > 0) {
7514						if (-1 == fwrite(buff, sizeof(char), sizeof(buff), dst_fd)) {
7515							switch(errno) {
7516							case ENOSPC:
7517								status = 507;
7518								break;
7519							default:
7520								status = 403;
7521								break;
7522							}
7523
7524							smbc_close(src_fd);
7525							fclose(dst_fd);
7526							unlink(photo_path);
7527
7528							curl_easy_cleanup(curl);
7529							con->http_status = status;
7530							return HANDLER_FINISHED;
7531						}
7532					}
7533				} while (ret > 0);
7534			}
7535
7536			smbc_close(src_fd);
7537			fclose(dst_fd);
7538
7539			FILE *fd;
7540 			fd = fopen(photo_path, "rb"); /* open file to upload */
7541		  	if(!fd) {
7542				unlink(photo_path);
7543				curl_easy_cleanup(curl);
7544		    	con->http_status = 404;
7545				return HANDLER_FINISHED;
7546		 	}
7547
7548			/* to get the file size */
7549			struct stat file_info;
7550  			if(fstat(fileno(fd), &file_info) != 0) {
7551				fclose(fd);
7552				unlink(photo_path);
7553				curl_easy_cleanup(curl);
7554		    	con->http_status = 404;
7555				return HANDLER_FINISHED;
7556			}
7557			#endif
7558
7559			long file_size = file_info.st_size;
7560			long l_photo_size_limit = atol(photo_size_limit->ptr);
7561			fclose(fd);
7562
7563			if(file_size>=l_photo_size_limit){
7564				unlink(photo_path);
7565				curl_easy_cleanup(curl);
7566		    	con->http_status = 501;
7567				return HANDLER_FINISHED;
7568			}
7569
7570			curl_formadd(&formpost, &lastptr,
7571			             CURLFORM_COPYNAME, "status",
7572			             CURLFORM_COPYCONTENTS, title->ptr, CURLFORM_END);
7573
7574			curl_formadd(&formpost, &lastptr,
7575			             CURLFORM_COPYNAME, "media[]",
7576			             CURLFORM_FILE, photo_path, CURLFORM_END);
7577
7578			curl_easy_setopt(curl, CURLOPT_VERBOSE, 2);
7579			curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
7580			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
7581			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
7582
7583			curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
7584
7585			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_func);
7586			curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_str);
7587
7588			Cdbg(DBE, "Uploading...");
7589			rt = curl_easy_perform(curl);
7590
7591			curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
7592
7593			Cdbg(DBE, "response_code=%d, response_str = %s", response_code, response_str);
7594
7595			free(response_str);
7596			unlink(photo_path);
7597
7598			/* Done. Cleanup. */
7599			curl_easy_cleanup(curl);
7600			curl_formfree(formpost);
7601		}
7602
7603
7604		if(response_code==200){
7605			con->http_status = 200;
7606		}
7607		else
7608			con->http_status = 501;
7609
7610		con->file_finished = 1;
7611		return HANDLER_FINISHED;
7612	}
7613
7614	case HTTP_METHOD_GETCPUUSAGE:{
7615		Cdbg(DBE, "do HTTP_METHOD_GETCPUUSAGE");
7616
7617#if EMBEDDED_EANBLE
7618		if(!con->srv_socket->is_ssl){
7619			con->http_status = 403;
7620			return HANDLER_FINISHED;
7621		}
7622#endif
7623
7624		int line_count = 0;
7625		int cpu_count = 0;
7626		unsigned long user, nice, system, idle, io, irq, softirq, i, j, k;
7627		char name[10], tmp[10], cpu_num[10];
7628		FILE *fp;
7629		fp = fopen("/proc/stat", "r");
7630
7631		if(fp == NULL){
7632			con->http_status = 400;
7633			return HANDLER_FINISHED;
7634		}
7635
7636		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
7637
7638		b = buffer_init();
7639
7640		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
7641		buffer_append_string_len(b,CONST_STR_LEN("<result>"));
7642
7643#if 1
7644		while(fscanf(fp, "%s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu \n", name, &user, &nice, &system, &idle, &io, &irq, &softirq, &i, &j, &k) != EOF){
7645
7646			if( strncmp( name, "cpu", 3 ) == 0 && strlen(name) > 3 ){
7647
7648				memset(cpu_num, 0, 10);
7649				replace_str( name, "cpu", "", cpu_num );
7650
7651				int cpu_index = atoi(cpu_num);
7652
7653				unsigned long total = user + nice + system + idle + io + irq + softirq;
7654				unsigned long total_diff = total - prev_total[cpu_index];
7655				unsigned long user_diff = ( user + nice + system + io + irq + softirq) - prev_user[cpu_index];
7656
7657				prev_total[cpu_index] = total;
7658				prev_user[cpu_index] = user + nice + system + io + irq + softirq;
7659
7660				unsigned long cpu_percentage = (100*user_diff/total_diff);
7661
7662				buffer_append_string_len(b, CONST_STR_LEN("<cpu"));
7663																																					buffer_append_string(b, cpu_num);
7664																																					buffer_append_string_len(b, CONST_STR_LEN(">"));
7665																																					memset(tmp, 0, 10);
7666																																					sprintf(tmp, "%lu", cpu_percentage);
7667				buffer_append_string(b, tmp);
7668																																					buffer_append_string_len(b, CONST_STR_LEN("</cpu"));
7669				buffer_append_string(b, cpu_num);
7670				buffer_append_string_len(b, CONST_STR_LEN(">"));
7671
7672				cpu_count++;
7673			}
7674
7675			line_count++;
7676
7677			if(line_count>=10)
7678				break;
7679
7680		}
7681#else
7682		while(fscanf(fp, "%s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu \n", name, &user, &nice, &system, &idle, &io, &irq, &softirq, &i, &j, &k) != EOF){
7683			//Cdbg(DBE, "name=%s", name);
7684			if(strcmp(name, "cpu0") == 0){
7685				unsigned long total_0_diff, user_0_diff, cpu0_percentage;
7686				total = user + nice + system + idle + io + irq + softirq;
7687				total_0_diff = total - prev_total_0;
7688				user_0_diff = (system + user + nice + io + irq + softirq) - prev_user_0;
7689				prev_total_0 = total;
7690				prev_user_0 = system + user + nice + io + irq + softirq;
7691				cpu0_percentage = (100*user_0_diff/total_0_diff);
7692
7693				buffer_append_string_len(b,CONST_STR_LEN("<cpu0>"));
7694				memset(tmp, 0, 10);
7695				sprintf(tmp, "%lu", cpu0_percentage);
7696				buffer_append_string(b,tmp);
7697				buffer_append_string_len(b,CONST_STR_LEN("</cpu0>"));
7698
7699				cpu_count++;
7700
7701			}
7702			else if(strcmp(name, "cpu1") == 0){
7703				unsigned long total_1_diff, user_1_diff, cpu1_percentage;
7704				total = user + nice + system + idle + io + irq + softirq;
7705				total_1_diff = total - prev_total_1;
7706				user_1_diff = (system + user + nice + io + irq + softirq) - prev_user_1;
7707				prev_total_1 = total;
7708				prev_user_1 = system + user + nice + io + irq + softirq;
7709				cpu1_percentage = (100*user_1_diff/total_1_diff);
7710
7711				buffer_append_string_len(b,CONST_STR_LEN("<cpu1>"));
7712				memset(tmp, 0, 10);
7713				sprintf(tmp, "%lu", cpu1_percentage);
7714				buffer_append_string(b,tmp);
7715				buffer_append_string_len(b,CONST_STR_LEN("</cpu1>"));
7716
7717				cpu_count++;
7718
7719			}
7720
7721			line_count++;
7722
7723			if(line_count>=3)
7724				break;
7725		}
7726#endif
7727
7728		fclose(fp);
7729
7730		buffer_append_string_len(b,CONST_STR_LEN("<cpucount>"));
7731		memset(tmp, 0, 10);
7732		sprintf(tmp, "%d", cpu_count);
7733		buffer_append_string(b,tmp);
7734		buffer_append_string_len(b,CONST_STR_LEN("</cpucount>"));
7735		buffer_append_string_len(b,CONST_STR_LEN("</result>"));
7736
7737		chunkqueue_append_buffer(con->write_queue, b);
7738		buffer_free(b);
7739
7740		con->http_status = 200;
7741		con->file_finished = 1;
7742		return HANDLER_FINISHED;
7743	}
7744
7745	case HTTP_METHOD_GETMEMORYUSAGE:{
7746		Cdbg(DBE, "do HTTP_METHOD_GETMEMORYUSAGE");
7747
7748#if EMBEDDED_EANBLE
7749		if(!con->srv_socket->is_ssl){
7750			con->http_status = 403;
7751			return HANDLER_FINISHED;
7752		}
7753#endif
7754
7755		unsigned long total, used, mfree;
7756		char buf[80], tmp[80];
7757		FILE *fp;
7758
7759		fp = fopen("/proc/meminfo", "r");
7760
7761		if(fp == NULL){
7762			con->http_status = 400;
7763			return HANDLER_FINISHED;
7764		}
7765
7766		fscanf(fp, "MemTotal: %lu %s\n", &total, buf);
7767		fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
7768		used = total - mfree;
7769		fclose(fp);
7770
7771		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
7772
7773		b = buffer_init();
7774
7775		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
7776		buffer_append_string_len(b, CONST_STR_LEN("<result>"));
7777
7778		buffer_append_string_len(b, CONST_STR_LEN("<Total>"));
7779		memset(tmp, 0, 80);
7780		sprintf(tmp, "%lu", total);
7781		buffer_append_string(b, tmp);
7782		buffer_append_string_len(b, CONST_STR_LEN("</Total>"));
7783
7784		buffer_append_string_len(b, CONST_STR_LEN("<Free>"));
7785		memset(tmp, 0, 80);
7786		sprintf(tmp, "%lu", mfree);
7787		buffer_append_string(b, tmp);
7788		buffer_append_string_len(b, CONST_STR_LEN("</Free>"));
7789
7790		buffer_append_string_len(b, CONST_STR_LEN("<Used>"));
7791		memset(tmp, 0, 80);
7792		sprintf(tmp, "%lu", used);
7793		buffer_append_string(b, tmp);
7794		buffer_append_string_len(b, CONST_STR_LEN("</Used>"));
7795
7796		buffer_append_string_len(b, CONST_STR_LEN("</result>"));
7797
7798		chunkqueue_append_buffer(con->write_queue, b);
7799		buffer_free(b);
7800
7801		con->http_status = 200;
7802		con->file_finished = 1;
7803		return HANDLER_FINISHED;
7804	}
7805
7806	case HTTP_METHOD_UPDATEACCOUNT:{
7807
7808		Cdbg(DBE, "do HTTP_METHOD_UPDATEACCOUNT");
7809
7810#if EMBEDDED_EANBLE
7811		if(!con->srv_socket->is_ssl){
7812			con->http_status = 403;
7813			return HANDLER_FINISHED;
7814		}
7815#endif
7816
7817		int userid = -1;
7818		buffer *username = buffer_init();
7819		buffer *password = buffer_init();
7820		buffer *type = buffer_init();
7821		buffer *permission = buffer_init();
7822
7823#ifdef USE_PROPPATCH
7824		if (con->request.content_length) {
7825			xmlDocPtr xml;
7826
7827			if (1 == smbdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
7828				xmlNode *rootnode = xmlDocGetRootElement(xml);
7829
7830				assert(rootnode);
7831
7832				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "content")) {
7833					xmlNode *cmd;
7834
7835					req_props = calloc(1, sizeof(*req_props));
7836
7837					for (cmd = rootnode->children; cmd; cmd = cmd->next) {
7838						if (0 == xmlStrcmp(cmd->name, BAD_CAST "id")) {
7839							userid = atoi(xmlNodeGetContent(cmd));
7840						}
7841						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "username")) {
7842							buffer_copy_string(username, xmlNodeGetContent(cmd));
7843							buffer_urldecode_path(username);
7844						}
7845						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "password")) {
7846							buffer_copy_string(password, xmlNodeGetContent(cmd));
7847							buffer_urldecode_path(password);
7848						}
7849						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "type")) {
7850							buffer_copy_string(type, xmlNodeGetContent(cmd));
7851							buffer_urldecode_path(type);
7852						}
7853						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "permission")) {
7854							buffer_copy_string(permission, xmlNodeGetContent(cmd));
7855							buffer_urldecode_path(permission);
7856						}
7857					}
7858				}
7859
7860				xmlFreeDoc(xml);
7861
7862			}
7863
7864		}
7865#endif
7866
7867		Cdbg(DBE, "UPDATEACCOUNT: userid=%d", userid);
7868		Cdbg(DBE, "UPDATEACCOUNT: username=%s", username->ptr);
7869		Cdbg(DBE, "UPDATEACCOUNT: password=%s", password->ptr);
7870		Cdbg(DBE, "UPDATEACCOUNT: type=%s", type->ptr);
7871		Cdbg(DBE, "UPDATEACCOUNT: permission=%s", permission->ptr);
7872
7873		if( buffer_is_empty(username) ||
7874			buffer_is_empty(password) ||
7875			buffer_is_empty(type) ||
7876			buffer_is_empty(permission) ){
7877			con->http_status = 400;
7878			return HANDLER_FINISHED;
7879		}
7880
7881		if(buffer_is_equal_string(type, CONST_STR_LEN("samba"))){
7882#if EMBEDDED_EANBLE
7883			add_account(username, password);
7884#endif
7885		}
7886		else if(buffer_is_equal_string(type, CONST_STR_LEN("aicloud"))){
7887
7888			aicloud_acc_info_t* c = NULL;
7889			int account_existed = 0;
7890
7891			for (c = aicloud_acc_info_list; c; c = c->next) {
7892				if(buffer_is_equal(c->username, username)){
7893					account_existed = 1;
7894					break;
7895				}
7896			}
7897
7898			if(userid==-1 && account_existed==1){
7899				//- account is already exised!
7900				b = buffer_init();
7901
7902				buffer_append_string_len(b, CONST_STR_LEN("ACCOUNT_IS_EXISTED"));
7903
7904				buffer_free(username);
7905				buffer_free(password);
7906				buffer_free(type);
7907				buffer_free(permission);
7908
7909				chunkqueue_append_buffer(con->write_queue, b);
7910				buffer_free(b);
7911
7912				con->http_status = 200;
7913				con->file_finished = 1;
7914				return HANDLER_FINISHED;
7915			}
7916
7917			if(userid==-1 && account_existed == 0){
7918				//- new
7919				aicloud_acc_info_t *aicloud_acc_info;
7920				aicloud_acc_info = (aicloud_acc_info_t *)calloc(1, sizeof(aicloud_acc_info_t));
7921
7922				//- User Name
7923				aicloud_acc_info->username = buffer_init();
7924				buffer_copy_buffer(aicloud_acc_info->username, username);
7925
7926				//- User Password
7927				aicloud_acc_info->password = buffer_init();
7928				buffer_copy_buffer(aicloud_acc_info->password, password);
7929
7930				DLIST_ADD(aicloud_acc_info_list, aicloud_acc_info);
7931			}
7932			else{
7933				//- update
7934				if(c!=NULL){
7935					buffer_copy_buffer(c->password, password);
7936				}
7937			}
7938
7939			save_aicloud_acc_list();
7940
7941			if(!buffer_is_empty(permission)){
7942
7943				char * pch;
7944				pch = strtok(permission->ptr, ",;");
7945
7946				while(pch!=NULL){
7947
7948					//- partion
7949					buffer* partion = buffer_init();
7950					buffer_copy_string_len(partion, CONST_STR_LEN("/mnt/") );
7951					buffer_append_string_len(partion, pch, strlen(pch));
7952					buffer_urldecode_path(partion);
7953
7954					//- folder
7955					pch = strtok(NULL,",;");
7956					buffer* folder = buffer_init();
7957					buffer_copy_string_len(folder, pch, strlen(pch));
7958					buffer_urldecode_path(folder);
7959
7960					//- permission
7961					pch = strtok(NULL,",;");
7962					buffer* permission = buffer_init();
7963					buffer_copy_string_len(permission, pch, strlen(pch));
7964
7965					Cdbg(DBE, "result: partion=%s, folder=%s, permission=%s", partion->ptr, folder->ptr, permission->ptr);
7966
7967#if EMBEDDED_EANBLE
7968					set_aicloud_permission( username->ptr,
7969											partion->ptr,
7970					  					    folder->ptr,
7971                 						    atoi(permission->ptr) );
7972#endif
7973
7974					buffer_free(partion);
7975					buffer_free(folder);
7976					buffer_free(permission);
7977
7978					pch = strtok(NULL,",;");
7979
7980				}
7981
7982			}
7983
7984			buffer_free(username);
7985			buffer_free(password);
7986			buffer_free(type);
7987			buffer_free(permission);
7988
7989		}
7990
7991		con->http_status = 200;
7992		con->file_finished = 1;
7993		return HANDLER_FINISHED;
7994	}
7995
7996	case HTTP_METHOD_DELETEACCOUNT:{
7997
7998		Cdbg(DBE, "do HTTP_METHOD_DELETEACCOUNT");
7999
8000#if EMBEDDED_EANBLE
8001		if(!con->srv_socket->is_ssl){
8002			con->http_status = 403;
8003			return HANDLER_FINISHED;
8004		}
8005#endif
8006
8007		buffer* username = NULL;
8008
8009		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "USERNAME"))) {
8010			username = ds->value;
8011			buffer_urldecode_path(username);
8012		} else {
8013			con->http_status = 400;
8014			return HANDLER_FINISHED;
8015		}
8016
8017		if(is_aicloud_account_existed(username->ptr)!=1){
8018			con->http_status = 400;
8019			return HANDLER_FINISHED;
8020		}
8021
8022		account_type var_type = smbc_get_account_type(username->ptr);
8023
8024		if(var_type == T_ACCOUNT_AICLOUD){
8025			aicloud_acc_info_t* c;
8026			for (c = aicloud_acc_info_list; c; c = c->next) {
8027				if(buffer_is_equal(c->username, username)){
8028					free_aicloud_acc_info(c);
8029					DLIST_REMOVE(aicloud_acc_info_list, c);
8030					free(c);
8031
8032					save_aicloud_acc_list();
8033
8034					break;
8035				}
8036			}
8037
8038#if EMBEDDED_EANBLE
8039
8040			disk_info_t *disk_list, *follow_disk;
8041			partition_info_t *follow_partition;
8042			char *var_file, *ptr;
8043			DIR *opened_dir;
8044			struct dirent *dp;
8045			int len;
8046
8047			disk_list = read_disk_data();
8048			if(disk_list != NULL){
8049
8050				for(follow_disk = disk_list; follow_disk != NULL; follow_disk = follow_disk->next){
8051					for(follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
8052						if(follow_partition->mount_point == NULL)
8053							continue;
8054
8055						if(get_aicloud_var_file_name(username->ptr, follow_partition->mount_point, &var_file)){
8056							continue;
8057						}
8058
8059						if((ptr = strrchr(var_file, '/')) == NULL){
8060							free(var_file);
8061							continue;
8062						}
8063
8064						if((opened_dir = opendir(follow_partition->mount_point)) == NULL){
8065							free(var_file);
8066							continue;
8067						}
8068
8069						++ptr;
8070
8071						len = strlen(ptr);
8072						while((dp = readdir(opened_dir)) != NULL){
8073							char test_path[PATH_MAX];
8074
8075							if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
8076								continue;
8077
8078							if(strncmp(dp->d_name, ptr, len))
8079								continue;
8080
8081							memset(test_path, 0, PATH_MAX);
8082							sprintf(test_path, "%s/%s", follow_partition->mount_point, dp->d_name);
8083
8084							delete_file_or_dir(test_path);
8085						}
8086						closedir(opened_dir);
8087
8088						free(var_file);
8089					}
8090				}
8091
8092				free_disk_data(&disk_list);
8093			}
8094
8095#endif
8096
8097		}
8098
8099		con->http_status = 200;
8100		con->file_finished = 1;
8101		return HANDLER_FINISHED;
8102	}
8103
8104	case HTTP_METHOD_GETACCOUNTINFO:{
8105		Cdbg(DBE, "do HTTP_METHOD_GETACCOUNTINFO");
8106
8107#if EMBEDDED_EANBLE
8108		if(!con->srv_socket->is_ssl){
8109			con->http_status = 403;
8110			return HANDLER_FINISHED;
8111		}
8112#endif
8113
8114		buffer* username = NULL;
8115
8116		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "USERNAME"))) {
8117			username = ds->value;
8118			buffer_urldecode_path(username);
8119		} else {
8120			con->http_status = 400;
8121			return HANDLER_FINISHED;
8122		}
8123
8124		//- Only admin or self can get account's info
8125		int has_query_permission = 0;
8126		data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
8127		if(ds!=NULL){
8128			smb_info_t *c;
8129			for (c = srv->smb_srv_info_list; c; c = c->next) {
8130
8131				if( buffer_is_equal(c->user_agent, ds->value) &&
8132				    buffer_is_equal(c->src_ip, con->dst_addr_buf) &&
8133				    buffer_is_empty(c->server) ){
8134
8135					if( smbc_get_account_permission(c->username->ptr) == T_ADMIN ||
8136						buffer_is_equal(username, c->username) ){
8137						has_query_permission = 1;
8138
8139						Cdbg(DBE, "c->username=%s", c->username->ptr);
8140					}
8141
8142					break;
8143				}
8144
8145			}
8146		}
8147
8148		if(has_query_permission==0){
8149			con->http_status = 400;
8150			return HANDLER_FINISHED;
8151		}
8152
8153		account_type var_type = smbc_get_account_type(username->ptr);
8154
8155		if(var_type != T_ACCOUNT_SAMBA && var_type != T_ACCOUNT_AICLOUD){
8156			con->http_status = 400;
8157			return HANDLER_FINISHED;
8158		}
8159
8160		con->http_status = 200;
8161
8162		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
8163
8164		b = buffer_init();
8165
8166		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
8167		buffer_append_string_len(b, CONST_STR_LEN("<result>"));
8168		buffer_append_string_len(b, CONST_STR_LEN("<username>"));
8169		buffer_append_string_buffer(b, username);
8170		buffer_append_string_len(b, CONST_STR_LEN("</username>"));
8171
8172		buffer_append_string_len(b, CONST_STR_LEN("<type>"));
8173		if(var_type == T_ACCOUNT_SAMBA)
8174			buffer_append_string_len(b, CONST_STR_LEN("samba"));
8175		else if(var_type == T_ACCOUNT_AICLOUD)
8176			buffer_append_string_len(b, CONST_STR_LEN("aicloud"));
8177		buffer_append_string_len(b, CONST_STR_LEN("</type>"));
8178
8179		buffer_append_string_len(b, CONST_STR_LEN("<permission>"));
8180		if(smbc_get_account_permission(username->ptr) == T_ADMIN)
8181			buffer_append_string_len(b, CONST_STR_LEN("admin"));
8182		else
8183			buffer_append_string_len(b, CONST_STR_LEN("user"));
8184		buffer_append_string_len(b, CONST_STR_LEN("</permission>"));
8185
8186		if(var_type == T_ACCOUNT_AICLOUD){
8187
8188			aicloud_acc_info_t* c;
8189			for (c = aicloud_acc_info_list; c; c = c->next) {
8190
8191				if(buffer_is_equal(c->username, username)){
8192					//- password
8193					buffer_append_string_len(b, CONST_STR_LEN("<password>"));
8194					buffer_append_string_buffer(b, c->password);
8195					buffer_append_string_len(b, CONST_STR_LEN("</password>"));
8196
8197					break;
8198				}
8199			}
8200
8201		}
8202		else if(var_type == T_ACCOUNT_SAMBA){
8203			//- password
8204			buffer_append_string_len(b, CONST_STR_LEN("<password>"));
8205			buffer_append_string_len(b, CONST_STR_LEN("</password>"));
8206
8207			//- name
8208			buffer_append_string_len(b, CONST_STR_LEN("<name>"));
8209			buffer_append_string_buffer(b, username);
8210			buffer_append_string_len(b, CONST_STR_LEN("</name>"));
8211		}
8212
8213		buffer_append_string_len(b, CONST_STR_LEN("</result>"));
8214
8215		chunkqueue_append_buffer(con->write_queue, b);
8216		buffer_free(b);
8217
8218		con->http_status = 200;
8219		con->file_finished = 1;
8220		return HANDLER_FINISHED;
8221	}
8222
8223	case HTTP_METHOD_GETACCOUNTLIST:{
8224		Cdbg(DBE, "do HTTP_METHOD_GETACCOUNTLIST");
8225
8226#if EMBEDDED_EANBLE
8227		if(!con->srv_socket->is_ssl){
8228			con->http_status = 403;
8229			return HANDLER_FINISHED;
8230		}
8231#endif
8232
8233		//- Only admin can get account's info
8234		if(is_connection_admin_permission(srv, con)==0){
8235			con->http_status = 400;
8236			return HANDLER_FINISHED;
8237		}
8238
8239		con->http_status = 200;
8240
8241		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
8242
8243		b = buffer_init();
8244
8245		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
8246		buffer_append_string_len(b, CONST_STR_LEN("<result>"));
8247
8248		char *nvram_acc_list;
8249
8250#if EMBEDDED_EANBLE
8251		char *a = nvram_get_acc_list();
8252		if(a==NULL) return -1;
8253		int l = strlen(a);
8254		nvram_acc_list = (char*)malloc(l+1);
8255		strncpy(nvram_acc_list, a, l);
8256		nvram_acc_list[l] = '\0';
8257		#ifdef APP_IPKG
8258		free(a);
8259		#endif
8260#else
8261		int i = 100;
8262		nvram_acc_list = (char*)malloc(100);
8263		strcpy(nvram_acc_list, "admin>admin<jerry>jerry");
8264#endif
8265		char * pch;
8266		pch = strtok(nvram_acc_list, "<>");
8267		while(pch!=NULL){
8268			int len;
8269
8270			//- User Name
8271			len = strlen(pch);
8272			char *name = (char*)malloc(len+1);
8273			strncpy(name, pch, len);
8274			name[len] = '\0';
8275			buffer* buffer_acc_name = buffer_init();
8276			buffer_copy_string(buffer_acc_name, name);
8277			buffer_urldecode_path(buffer_acc_name);
8278			free(name);
8279
8280			//- User Password
8281			pch = strtok(NULL,"<>");
8282
8283			buffer_append_string_len(b, CONST_STR_LEN("<account>"));
8284
8285			//- id
8286			buffer_append_string_len(b, CONST_STR_LEN("<id>"));
8287			buffer_append_string_len(b, CONST_STR_LEN("</id>"));
8288
8289			//- username
8290			buffer_append_string_len(b, CONST_STR_LEN("<username>"));
8291			buffer_append_string_buffer(b, buffer_acc_name);
8292			buffer_append_string_len(b, CONST_STR_LEN("</username>"));
8293
8294			//- name
8295			buffer_append_string_len(b, CONST_STR_LEN("<name>"));
8296			buffer_append_string_buffer(b, buffer_acc_name);
8297			buffer_append_string_len(b, CONST_STR_LEN("</name>"));
8298
8299			//- type
8300			buffer_append_string_len(b, CONST_STR_LEN("<type>"));
8301			buffer_append_string_len(b, CONST_STR_LEN("samba"));
8302			buffer_append_string_len(b, CONST_STR_LEN("</type>"));
8303
8304			buffer_append_string_len(b, CONST_STR_LEN("</account>"));
8305
8306			buffer_free(buffer_acc_name);
8307
8308			//- next Name>Password
8309			pch = strtok(NULL,"<>");
8310
8311		}
8312
8313		free(nvram_acc_list);
8314
8315		aicloud_acc_info_t* c;
8316		for (c = aicloud_acc_info_list; c; c = c->next) {
8317
8318			buffer_append_string_len(b, CONST_STR_LEN("<account>"));
8319
8320			//- username
8321			buffer_append_string_len(b, CONST_STR_LEN("<username>"));
8322			buffer_append_string_buffer(b, c->username);
8323			buffer_append_string_len(b, CONST_STR_LEN("</username>"));
8324
8325			//- type
8326			buffer_append_string_len(b, CONST_STR_LEN("<type>"));
8327			buffer_append_string_len(b, CONST_STR_LEN("aicloud"));
8328			buffer_append_string_len(b, CONST_STR_LEN("</type>"));
8329
8330			buffer_append_string_len(b, CONST_STR_LEN("</account>"));
8331		}
8332
8333		chunkqueue_append_buffer(con->write_queue, b);
8334		buffer_free(b);
8335
8336
8337		con->http_status = 200;
8338		con->file_finished = 1;
8339		return HANDLER_FINISHED;
8340	}
8341
8342	case HTTP_METHOD_UPDATEACCOUNTINVITE:{
8343		Cdbg(DBE, "do HTTP_METHOD_UPDATEACCOUNTINVITE");
8344
8345#if EMBEDDED_EANBLE
8346		if(!con->srv_socket->is_ssl){
8347			con->http_status = 403;
8348			return HANDLER_FINISHED;
8349		}
8350#endif
8351
8352		//- Only admin can get account's info
8353		if(is_connection_admin_permission(srv, con)==0){
8354			con->http_status = 400;
8355			return HANDLER_FINISHED;
8356		}
8357
8358		buffer *token = buffer_init();
8359		buffer *permission = buffer_init();
8360		int enable_smart_access = 0;
8361		buffer *security_code = buffer_init();
8362
8363#ifdef USE_PROPPATCH
8364		if (con->request.content_length) {
8365			xmlDocPtr xml;
8366
8367			if (1 == smbdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
8368				xmlNode *rootnode = xmlDocGetRootElement(xml);
8369
8370				assert(rootnode);
8371
8372				if (0 == xmlStrcmp(rootnode->name, BAD_CAST "content")) {
8373					xmlNode *cmd;
8374
8375					req_props = calloc(1, sizeof(*req_props));
8376
8377					for (cmd = rootnode->children; cmd; cmd = cmd->next) {
8378						if (0 == xmlStrcmp(cmd->name, BAD_CAST "token")) {
8379							buffer_copy_string(token, xmlNodeGetContent(cmd));
8380							buffer_urldecode_path(token);
8381						}
8382						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "permission")) {
8383							buffer_copy_string(permission, xmlNodeGetContent(cmd));
8384							buffer_urldecode_path(permission);
8385						}
8386						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "enable_smart_access")) {
8387							enable_smart_access = atoi(xmlNodeGetContent(cmd));
8388						}
8389						else if (0 == xmlStrcmp(cmd->name, BAD_CAST "security_code")) {
8390							buffer_copy_string(security_code, xmlNodeGetContent(cmd));
8391						}
8392					}
8393				}
8394
8395				xmlFreeDoc(xml);
8396
8397			}
8398
8399		}
8400#endif
8401
8402		Cdbg(DBE, "HTTP_METHOD_UPDATEACCOUNTINVITE: token=%s permission=%s, enable_smart_access=%d, security_code=%s",
8403			token->ptr, permission->ptr, enable_smart_access, security_code->ptr);
8404
8405		if( buffer_is_empty(permission) ){
8406			con->http_status = 400;
8407			return HANDLER_FINISHED;
8408		}
8409
8410		aicloud_acc_invite_info_t *aicloud_acc_invite_info = NULL;
8411		#if EMBEDDED_EANBLE
8412		char *productid = nvram_get_productid();
8413		char *aae_deviceid = nvram_get_value("aae_deviceid");
8414		#else
8415		char *productid = "usbdisk";
8416		char *aae_deviceid = "";
8417		#endif
8418
8419		/* create a invite-token */
8420		char invite_token[37] /* 36 + \0 */;
8421
8422		if(buffer_is_empty(token) || buffer_is_equal_string(token, "", 0)){
8423			struct timeval tv;
8424			unsigned long long now_utime;
8425			gettimeofday(&tv,NULL);
8426			now_utime = tv.tv_sec * 1000000 + tv.tv_usec;
8427			sprintf( invite_token, "AINVITE%d", abs(now_utime));
8428
8429			//- new
8430			aicloud_acc_invite_info = (aicloud_acc_invite_info_t *)calloc(1, sizeof(aicloud_acc_invite_info_t));
8431
8432			//- productid
8433			aicloud_acc_invite_info->productid = buffer_init();
8434			buffer_copy_string(aicloud_acc_invite_info->productid, productid);
8435
8436			//- deviceid
8437			aicloud_acc_invite_info->deviceid = buffer_init();
8438			buffer_copy_string(aicloud_acc_invite_info->deviceid, aae_deviceid);
8439
8440			//- token
8441			aicloud_acc_invite_info->token = buffer_init();
8442			buffer_copy_string(aicloud_acc_invite_info->token, invite_token);
8443
8444			//- permission
8445			aicloud_acc_invite_info->permission = buffer_init();
8446			buffer_copy_buffer(aicloud_acc_invite_info->permission, permission);
8447
8448			//- bytes_in_avail
8449			aicloud_acc_invite_info->bytes_in_avail = 0;
8450
8451			//- smart_access
8452			aicloud_acc_invite_info->smart_access= enable_smart_access;
8453
8454			//- security_code
8455			aicloud_acc_invite_info->security_code = buffer_init();
8456			buffer_copy_buffer(aicloud_acc_invite_info->security_code, security_code);
8457
8458			//- status
8459			aicloud_acc_invite_info->status = 0;
8460
8461			//- auth_type
8462			aicloud_acc_invite_info->auth_type = 0;
8463
8464			//- createtime
8465			aicloud_acc_invite_info->createtime = srv->cur_ts;
8466
8467			DLIST_ADD(aicloud_acc_invite_info_list, aicloud_acc_invite_info);
8468		}
8469		else{
8470			int bFound = 0;
8471			for (aicloud_acc_invite_info = aicloud_acc_invite_info_list; aicloud_acc_invite_info; aicloud_acc_invite_info = aicloud_acc_invite_info->next) {
8472				if(buffer_is_equal(aicloud_acc_invite_info->token, token)){
8473					strcpy(invite_token, aicloud_acc_invite_info->token->ptr);
8474					bFound = 1;
8475					break;
8476				}
8477			}
8478
8479			if(bFound==0){
8480				con->http_status = 400;
8481				return HANDLER_FINISHED;
8482			}
8483
8484			//- permission
8485			aicloud_acc_invite_info->permission = buffer_init();
8486			buffer_copy_buffer(aicloud_acc_invite_info->permission, permission);
8487
8488			//- smart_access
8489			aicloud_acc_invite_info->smart_access = enable_smart_access;
8490
8491			//- security_code
8492			aicloud_acc_invite_info->security_code = buffer_init();
8493			buffer_copy_buffer(aicloud_acc_invite_info->security_code, security_code);
8494		}
8495
8496#if EMBEDDED_EANBLE
8497#ifdef APP_IPKG
8498		free(productid);
8499		free(aae_deviceid);
8500#endif
8501#endif
8502
8503		save_aicloud_acc_invite_list();
8504
8505		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
8506
8507		b = buffer_init();
8508
8509		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
8510		buffer_append_string_len(b, CONST_STR_LEN("<result>"));
8511		buffer_append_string_len(b, CONST_STR_LEN("<token>"));
8512		buffer_append_string(b, invite_token);
8513		buffer_append_string_len(b, CONST_STR_LEN("</token>"));
8514		buffer_append_string_len(b, CONST_STR_LEN("</result>"));
8515
8516		chunkqueue_append_buffer(con->write_queue, b);
8517		buffer_free(b);
8518
8519		con->http_status = 200;
8520		con->file_finished = 1;
8521		return HANDLER_FINISHED;
8522	}
8523
8524	case HTTP_METHOD_GETACCOUNTINVITELIST:{
8525		Cdbg(DBE, "do HTTP_METHOD_GETACCOUNTINVITELIST");
8526
8527#if EMBEDDED_EANBLE
8528		if(!con->srv_socket->is_ssl){
8529			con->http_status = 403;
8530			return HANDLER_FINISHED;
8531		}
8532#endif
8533
8534		//- Only admin can get account's info
8535		if(is_connection_admin_permission(srv, con)==0){
8536			con->http_status = 400;
8537			return HANDLER_FINISHED;
8538		}
8539
8540		con->http_status = 200;
8541
8542		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
8543
8544		b = buffer_init();
8545
8546		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
8547		buffer_append_string_len(b, CONST_STR_LEN("<result>"));
8548
8549		aicloud_acc_invite_info_t *c;
8550		for (c = aicloud_acc_invite_info_list; c; c = c->next) {
8551
8552			buffer_append_string_len(b, CONST_STR_LEN("<invite>"));
8553
8554			//- token
8555			buffer_append_string_len(b, CONST_STR_LEN("<token>"));
8556			buffer_append_string_buffer(b, c->token);
8557			buffer_append_string_len(b, CONST_STR_LEN("</token>"));
8558			Cdbg(1, "c->token=%s", c->token->ptr);
8559			//- smart_access
8560			buffer_append_string_len(b, CONST_STR_LEN("<smart_access>"));
8561			char strSmartAccess[2] = {0};
8562			sprintf(strSmartAccess, "%d", c->smart_access);
8563			buffer_append_string(b, strSmartAccess);
8564			buffer_append_string_len(b, CONST_STR_LEN("</smart_access>"));
8565			Cdbg(1, "c->smart_access=%d", c->smart_access);
8566
8567			//- security_code
8568			buffer_append_string_len(b, CONST_STR_LEN("<security_code>"));
8569			buffer_append_string_buffer(b, c->security_code);
8570			buffer_append_string_len(b, CONST_STR_LEN("</security_code>"));
8571			Cdbg(1, "c->security_code=%s", c->security_code->ptr);
8572
8573			//- timestamp
8574			buffer_append_string_len(b, CONST_STR_LEN("<timestamp>"));
8575			buffer_append_strftime(b, "%Y-%m-%d %H:%M:%S", localtime(&(c->createtime)));
8576			buffer_append_string_len(b, CONST_STR_LEN("</timestamp>"));
8577
8578			buffer_append_string_len(b, CONST_STR_LEN("</invite>"));
8579		}
8580
8581		buffer_append_string_len(b, CONST_STR_LEN("</result>"));
8582
8583		chunkqueue_append_buffer(con->write_queue, b);
8584		buffer_free(b);
8585
8586		con->http_status = 200;
8587		con->file_finished = 1;
8588		return HANDLER_FINISHED;
8589	}
8590
8591	case HTTP_METHOD_GETACCOUNTINVITEINFO:{
8592		Cdbg(DBE, "do HTTP_METHOD_GETACCOUNTINVITEINFO");
8593
8594#if EMBEDDED_EANBLE
8595		if(!con->srv_socket->is_ssl){
8596			con->http_status = 403;
8597			return HANDLER_FINISHED;
8598		}
8599#endif
8600
8601		buffer* invite_token = NULL;
8602
8603		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
8604			invite_token = ds->value;
8605		} else {
8606			con->http_status = 400;
8607			return HANDLER_FINISHED;
8608		}
8609
8610		//- Only admin can get account's invite info
8611		int has_query_permission = 0;
8612		data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent");
8613		if(ds!=NULL){
8614			smb_info_t *c;
8615			for (c = srv->smb_srv_info_list; c; c = c->next) {
8616
8617				if( buffer_is_equal(c->user_agent, ds->value) &&
8618					buffer_is_equal(c->src_ip, con->dst_addr_buf) &&
8619					buffer_is_empty(c->server) ){
8620
8621					if( smbc_get_account_permission(c->username->ptr) == T_ADMIN ){
8622						has_query_permission = 1;
8623					}
8624
8625					break;
8626				}
8627
8628			}
8629		}
8630
8631		if(has_query_permission==0){
8632			con->http_status = 400;
8633			return HANDLER_FINISHED;
8634		}
8635
8636		int bFound = 0;
8637		aicloud_acc_invite_info_t *c;
8638		for (c = aicloud_acc_invite_info_list; c; c = c->next) {
8639			if(buffer_is_equal(c->token, invite_token)){
8640				bFound = 1;
8641				break;
8642			}
8643		}
8644
8645		if(bFound==0){
8646			con->http_status = 400;
8647			return HANDLER_FINISHED;
8648		}
8649
8650		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
8651
8652		b = buffer_init();
8653
8654		buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
8655		buffer_append_string_len(b, CONST_STR_LEN("<result>"));
8656
8657		buffer_append_string_len(b, CONST_STR_LEN("<permission>"));
8658		buffer_append_string_buffer(b, c->permission);
8659		buffer_append_string_len(b, CONST_STR_LEN("</permission>"));
8660
8661		buffer_append_string_len(b, CONST_STR_LEN("<smart_access>"));
8662		char strSmartAccess[2] = {0};
8663		sprintf(strSmartAccess, "%d", c->smart_access);
8664		buffer_append_string(b, strSmartAccess);
8665		buffer_append_string_len(b, CONST_STR_LEN("</smart_access>"));
8666
8667		buffer_append_string_len(b, CONST_STR_LEN("<security_code>"));
8668		buffer_append_string_buffer(b, c->security_code);
8669		buffer_append_string_len(b, CONST_STR_LEN("</security_code>"));
8670
8671		buffer_append_string_len(b, CONST_STR_LEN("</result>"));
8672
8673		chunkqueue_append_buffer(con->write_queue, b);
8674		buffer_free(b);
8675
8676		con->http_status = 200;
8677		con->file_finished = 1;
8678		return HANDLER_FINISHED;
8679	}
8680
8681	case HTTP_METHOD_DELETEACCOUNTINVITE:{
8682		Cdbg(DBE, "do HTTP_METHOD_DELETEACCOUNTINVITE");
8683
8684#if EMBEDDED_EANBLE
8685		if(!con->srv_socket->is_ssl){
8686			con->http_status = 403;
8687			return HANDLER_FINISHED;
8688		}
8689#endif
8690
8691		//- Only admin can get account's info
8692		if(is_connection_admin_permission(srv, con)==0){
8693			con->http_status = 400;
8694			return HANDLER_FINISHED;
8695		}
8696
8697		buffer* invite_token = NULL;
8698
8699		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
8700			invite_token = ds->value;
8701		} else {
8702			con->http_status = 400;
8703			return HANDLER_FINISHED;
8704		}
8705
8706		aicloud_acc_invite_info_t *c;
8707		for (c = aicloud_acc_invite_info_list; c; c = c->next) {
8708			if(buffer_is_equal(c->token, invite_token)){
8709				free_aicloud_acc_invite_info(c);
8710				DLIST_REMOVE(aicloud_acc_invite_info_list, c);
8711				free(c);
8712
8713				save_aicloud_acc_invite_list();
8714
8715				break;
8716			}
8717		}
8718
8719		con->http_status = 200;
8720		con->file_finished = 1;
8721		return HANDLER_FINISHED;
8722	}
8723
8724#if 0
8725	case HTTP_METHOD_UPDATEACCOUNTINVITE:{
8726		Cdbg(DBE, "do HTTP_METHOD_UPDATEACCOUNTINVITE");
8727
8728#if EMBEDDED_EANBLE
8729		if(!con->srv_socket->is_ssl){
8730			con->http_status = 403;
8731			return HANDLER_FINISHED;
8732		}
8733#endif
8734
8735		buffer* buffer_token = NULL;
8736		buffer* buffer_username = NULL;
8737		buffer* buffer_password = NULL;
8738
8739		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "TOKEN"))) {
8740			buffer_token = ds->value;
8741		} else {
8742			con->http_status = 400;
8743			return HANDLER_FINISHED;
8744		}
8745
8746		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "USERNAME"))) {
8747			buffer_username = ds->value;
8748		} else {
8749			con->http_status = 400;
8750			return HANDLER_FINISHED;
8751		}
8752
8753		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "PASSWORD"))) {
8754			buffer_password = ds->value;
8755		} else {
8756			con->http_status = 400;
8757			return HANDLER_FINISHED;
8758		}
8759
8760		int bFoundToken = 0;
8761		aicloud_acc_invite_info_t *c;
8762		for (c = aicloud_acc_invite_info_list; c; c = c->next) {
8763			if(buffer_is_equal(c->token, buffer_token)){
8764				bFoundToken = 1;
8765				break;
8766			}
8767		}
8768
8769		if(bFoundToken==0){
8770			con->http_status = 400;
8771			return HANDLER_FINISHED;
8772		}
8773
8774		if(c->status != 0){
8775			con->http_status = 400;
8776			return HANDLER_FINISHED;
8777		}
8778
8779		//- check username
8780		if(is_account_existed(buffer_username->ptr)==1){
8781			con->http_status = 400;
8782			return HANDLER_FINISHED;
8783		}
8784
8785		//- add account
8786		aicloud_acc_info_t *aicloud_acc_info;
8787		aicloud_acc_info = (aicloud_acc_info_t *)calloc(1, sizeof(aicloud_acc_info_t));
8788
8789		//- User Name
8790		aicloud_acc_info->username = buffer_init();
8791		buffer_copy_buffer(aicloud_acc_info->username, buffer_username);
8792
8793		//- User Password
8794		aicloud_acc_info->password = buffer_init();
8795		buffer_copy_buffer(aicloud_acc_info->password, buffer_password);
8796
8797		DLIST_ADD(aicloud_acc_info_list, aicloud_acc_info);
8798
8799		save_aicloud_acc_list();
8800
8801		//- create permission
8802		if(!buffer_is_empty(c->permission)){
8803
8804			char * pch;
8805			pch = strtok(c->permission->ptr, ",;");
8806
8807			while(pch!=NULL){
8808
8809				//- partion
8810				buffer* partion = buffer_init();
8811				buffer_copy_string_len(partion, CONST_STR_LEN("/mnt/") );
8812				buffer_append_string_len(partion, pch, strlen(pch));
8813				buffer_urldecode_path(partion);
8814
8815				//- folder
8816				pch = strtok(NULL,",;");
8817				buffer* folder = buffer_init();
8818				buffer_copy_string_len(folder, pch, strlen(pch));
8819				buffer_urldecode_path(folder);
8820
8821				//- permission
8822				pch = strtok(NULL,",;");
8823				buffer* permission = buffer_init();
8824				buffer_copy_string_len(permission, pch, strlen(pch));
8825
8826				Cdbg(DBE, "result: partion=%s, folder=%s, permission=%s", partion->ptr, folder->ptr, permission->ptr);
8827
8828#if EMBEDDED_EANBLE
8829				set_aicloud_permission( buffer_username->ptr,
8830										partion->ptr,
8831				  					    folder->ptr,
8832               						    atoi(c->permission->ptr) );
8833#endif
8834				buffer_free(partion);
8835				buffer_free(folder);
8836				buffer_free(permission);
8837
8838				pch = strtok(NULL,",;");
8839
8840			}
8841
8842		}
8843
8844		//- delete invite token
8845		free_aicloud_acc_invite_info(c);
8846		DLIST_REMOVE(aicloud_acc_invite_info_list, c);
8847		free(c);
8848
8849		save_aicloud_acc_invite_list();
8850
8851		con->http_status = 200;
8852		con->file_finished = 1;
8853		return HANDLER_FINISHED;
8854	}
8855#endif
8856
8857	case HTTP_METHOD_OPENSTREAMINGPORT:{
8858		Cdbg(DBE, "do HTTP_METHOD_OPENSTREAMINGPORT");
8859
8860#if EMBEDDED_EANBLE
8861		if(!con->srv_socket->is_ssl){
8862			con->http_status = 403;
8863			return HANDLER_FINISHED;
8864		}
8865#endif
8866
8867		int open = 0;
8868
8869		if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "OPEN"))) {
8870			open = atoi(ds->value->ptr);
8871		} else {
8872			con->http_status = 400;
8873			return HANDLER_FINISHED;
8874		}
8875
8876		open_close_streaming_port(srv, open);
8877
8878		con->http_status = 200;
8879		con->file_finished = 1;
8880		return HANDLER_FINISHED;
8881	}
8882
8883	default:
8884		break;
8885	}
8886
8887	/* not found */
8888	return HANDLER_GO_ON;
8889}
8890
8891URIHANDLER_FUNC(mod_smbdav_trigger_handler){
8892#ifdef EMBEDDED_EANBLE
8893
8894#if 0
8895	time_t cur_ts = time(NULL);
8896
8897	//- stop arp every 2 hour
8898	if(prv_ts != 0 && cur_ts - prv_ts >= 7200){
8899		stop_arpping_process();
8900		prv_ts = cur_ts;
8901	}
8902#endif
8903
8904	/*if( srv->last_no_ssl_connection_ts == 0 ){
8905
8906		if(prv_ts==0){
8907			prv_ts = srv->cur_ts;
8908		}
8909		else{
8910			if(srv->cur_ts - prv_ts >=20){
8911				//- After init the lighttpd, close the streaming port after 20 seconds.
8912				open_close_streaming_port(srv, 0);
8913			}
8914		}
8915
8916	}
8917	else */if( srv->last_no_ssl_connection_ts == 0 ||
8918		     (srv->is_streaming_port_opend == 1 && srv->cur_ts - srv->last_no_ssl_connection_ts >= 7200/*2 hour*/ )){
8919		//- close streaming port
8920		open_close_streaming_port(srv, 0);
8921	}
8922#else
8923	start_arpping_process(srv->srvconf.arpping_interface->ptr);
8924#endif
8925
8926	return HANDLER_GO_ON;
8927}
8928
8929/* this function is called at dlopen() time and inits the callbacks */
8930#ifndef APP_IPKG
8931int mod_smbdav_plugin_init(plugin *p) {
8932
8933	p->version     = LIGHTTPD_VERSION_ID;
8934	p->name        = buffer_init_string("smbdav");
8935
8936	p->init        = mod_smbdav_init;
8937
8938	p->handle_uri_clean  = mod_smbdav_uri_handler;
8939	p->handle_physical   = mod_smbdav_subrequest_handler;
8940	p->set_defaults  = mod_smbdav_set_defaults;
8941	p->cleanup     = mod_smbdav_free;
8942	p->data        = NULL;
8943	p->handle_connection_close = mod_msbdav_connection_close;
8944
8945#ifdef EMBEDDED_EANBLE
8946	//- Jerry add 20110930
8947	p->handle_trigger = mod_smbdav_trigger_handler;
8948#endif
8949
8950	read_aicloud_acc_list();
8951	read_aicloud_acc_invite_list();
8952	read_sharelink_list();
8953
8954	return 0;
8955}
8956#else
8957int aicloud_mod_smbdav_plugin_init(plugin *p) {
8958
8959	p->version     = LIGHTTPD_VERSION_ID;
8960	p->name        = buffer_init_string("smbdav");
8961
8962	p->init        = mod_smbdav_init;
8963
8964	p->handle_uri_clean  = mod_smbdav_uri_handler;
8965	p->handle_physical   = mod_smbdav_subrequest_handler;
8966	p->set_defaults  = mod_smbdav_set_defaults;
8967	p->cleanup     = mod_smbdav_free;
8968	p->data        = NULL;
8969	p->handle_connection_close = mod_msbdav_connection_close;
8970
8971#ifdef EMBEDDED_EANBLE
8972	//- Jerry add 20110930
8973	p->handle_trigger = mod_smbdav_trigger_handler;
8974#endif
8975
8976	read_aicloud_acc_list();
8977	read_aicloud_acc_invite_list();
8978	read_sharelink_list();
8979
8980	return 0;
8981}
8982#endif
8983
8984//#endif
8985
8986