fixed a bug that the remaining buffer capacity is calculated incorrectly when returning a footer to directory listing.
switched snprintf to qse_mbsxfmt() and qse_mbsxfmts(). added qse_mbsfmts()/qse_wcsfmts() and variants
This commit is contained in:
		| @ -14,7 +14,6 @@ | |||||||
|  |  | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <locale.h> | #include <locale.h> | ||||||
| #include <stdio.h> |  | ||||||
|  |  | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| #	include <winsock2.h> | #	include <winsock2.h> | ||||||
|  | |||||||
| @ -17,7 +17,6 @@ | |||||||
|  |  | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <locale.h> | #include <locale.h> | ||||||
| #include <stdio.h> |  | ||||||
|  |  | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| #	include <winsock2.h> | #	include <winsock2.h> | ||||||
|  | |||||||
| @ -706,7 +706,7 @@ QSE_EXPORT qse_size_t qse_mbsvfmt ( | |||||||
|  *   terminating null. When \a buf is #QSE_NULL, it returns the number of  |  *   terminating null. When \a buf is #QSE_NULL, it returns the number of  | ||||||
|  *   characters that would have been written excluding the terminating null |  *   characters that would have been written excluding the terminating null | ||||||
|  *   if \a buf has not been #QSE_NULL. If conversion from a wide-character  |  *   if \a buf has not been #QSE_NULL. If conversion from a wide-character  | ||||||
|  *   string failure, it returns (qse_size_t)-1. |  *   string fails, it returns (qse_size_t)-1. | ||||||
|  */ |  */ | ||||||
| QSE_EXPORT qse_size_t qse_mbsxfmt ( | QSE_EXPORT qse_size_t qse_mbsxfmt ( | ||||||
| 	qse_mchar_t*       buf, | 	qse_mchar_t*       buf, | ||||||
| @ -722,6 +722,36 @@ QSE_EXPORT qse_size_t qse_mbsxvfmt ( | |||||||
| 	va_list            ap | 	va_list            ap | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_mbsfmts ( | ||||||
|  | 	qse_mchar_t*       buf, | ||||||
|  | 	const qse_mchar_t* fmt, | ||||||
|  | 	... | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_mbsvfmts ( | ||||||
|  | 	qse_mchar_t*       buf, | ||||||
|  | 	const qse_mchar_t* fmt, | ||||||
|  | 	va_list            ap | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The qse_mbsxfmt() function behaves the same as qse_mbsxfmt() except | ||||||
|  |  * that it returns (qse_size_t)-1 if the buffer is not large enough.  | ||||||
|  |  */ | ||||||
|  | QSE_EXPORT qse_size_t qse_mbsxfmts ( | ||||||
|  | 	qse_mchar_t*       buf, | ||||||
|  | 	qse_size_t         bsz, | ||||||
|  | 	const qse_mchar_t* fmt, | ||||||
|  | 	... | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_mbsxvfmts ( | ||||||
|  | 	qse_mchar_t*       buf, | ||||||
|  | 	qse_size_t         bsz, | ||||||
|  | 	const qse_mchar_t* fmt, | ||||||
|  | 	va_list            ap | ||||||
|  | ); | ||||||
|  |  | ||||||
| QSE_EXPORT qse_size_t qse_wcsfmt ( | QSE_EXPORT qse_size_t qse_wcsfmt ( | ||||||
| 	qse_wchar_t*       buf, | 	qse_wchar_t*       buf, | ||||||
| 	const qse_wchar_t* fmt, | 	const qse_wchar_t* fmt, | ||||||
| @ -763,17 +793,56 @@ QSE_EXPORT qse_size_t qse_wcsxvfmt ( | |||||||
| 	va_list            ap | 	va_list            ap | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_wcsfmts ( | ||||||
|  | 	qse_wchar_t*       buf, | ||||||
|  | 	const qse_wchar_t* fmt, | ||||||
|  | 	... | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_wcsvfmts ( | ||||||
|  | 	qse_wchar_t*       buf, | ||||||
|  | 	const qse_wchar_t* fmt, | ||||||
|  | 	va_list            ap | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The qse_wcsxfmts() function behaves the same as qse_wcsxfmt() except | ||||||
|  |  * that it returns (qse_size_t)-1 if the buffer is not large enough. | ||||||
|  |  */ | ||||||
|  | QSE_EXPORT qse_size_t qse_wcsxfmts ( | ||||||
|  | 	qse_wchar_t*       buf, | ||||||
|  | 	qse_size_t         bsz, | ||||||
|  | 	const qse_wchar_t* fmt, | ||||||
|  | 	... | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_wcsxvfmts ( | ||||||
|  | 	qse_wchar_t*       buf, | ||||||
|  | 	qse_size_t         bsz, | ||||||
|  | 	const qse_wchar_t* fmt, | ||||||
|  | 	va_list            ap | ||||||
|  | ); | ||||||
|  |  | ||||||
| #if defined(QSE_CHAR_IS_MCHAR) | #if defined(QSE_CHAR_IS_MCHAR) | ||||||
| #	define qse_strfmt qse_mbsfmt | #	define qse_strfmt qse_mbsfmt | ||||||
| #	define qse_strvfmt qse_mbsvfmt | #	define qse_strvfmt qse_mbsvfmt | ||||||
| #	define qse_strxfmt qse_mbsxfmt | #	define qse_strxfmt qse_mbsxfmt | ||||||
| #	define qse_strxvfmt qse_mbsxvfmt | #	define qse_strxvfmt qse_mbsxvfmt | ||||||
|  |  | ||||||
|  | #	define qse_strfmts qse_mbsfmts | ||||||
|  | #	define qse_strvfmts qse_mbsvfmts | ||||||
|  | #	define qse_strxfmts qse_mbsxfmts | ||||||
|  | #	define qse_strxvfmts qse_mbsxvfmts | ||||||
| #else | #else | ||||||
| #	define qse_strfmt qse_wcsfmt | #	define qse_strfmt qse_wcsfmt | ||||||
| #	define qse_strvfmt qse_wcsvfmt | #	define qse_strvfmt qse_wcsvfmt | ||||||
| #	define qse_strxfmt qse_wcsxfmt | #	define qse_strxfmt qse_wcsxfmt | ||||||
| #	define qse_strxvfmt qse_wcsxvfmt | #	define qse_strxvfmt qse_wcsxvfmt | ||||||
|  |  | ||||||
|  | #	define qse_strfmts qse_wcsfmts | ||||||
|  | #	define qse_strvfmts qse_wcsvfmts | ||||||
|  | #	define qse_strxfmts qse_wcsxfmts | ||||||
|  | #	define qse_strxvfmts qse_wcsxvfmts | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  | |||||||
| @ -77,6 +77,35 @@ static int put_wchar (qse_wchar_t c, void* ctx) | |||||||
| 	return 0;  | 	return 0;  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int put_mchar_strict (qse_mchar_t c, void* ctx) | ||||||
|  | { | ||||||
|  | 	mbuf_t* buf = (mbuf_t*)ctx; | ||||||
|  |  | ||||||
|  | 	if (buf->len < buf->capa)  | ||||||
|  | 	{ | ||||||
|  | 		buf->ptr[buf->len++] = c; | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* buffer is full stop. return error */ | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int put_wchar_strict (qse_wchar_t c, void* ctx) | ||||||
|  | { | ||||||
|  | 	wbuf_t* buf = (wbuf_t*)ctx; | ||||||
|  |  | ||||||
|  | 	if (buf->len < buf->capa)  | ||||||
|  | 	{ | ||||||
|  | 		buf->ptr[buf->len++] = c; | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* buffer is full stop. return error */ | ||||||
|  | 	return -1;  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static int wcs_to_mbs ( | static int wcs_to_mbs ( | ||||||
| 	const qse_wchar_t* wcs, qse_size_t* wcslen, | 	const qse_wchar_t* wcs, qse_size_t* wcslen, | ||||||
| 	qse_mchar_t* mbs, qse_size_t* mbslen, void* ctx) | 	qse_mchar_t* mbs, qse_size_t* mbslen, void* ctx) | ||||||
| @ -135,6 +164,35 @@ static int mbs_to_wcs ( | |||||||
| #undef strvfmt | #undef strvfmt | ||||||
| #undef strxvfmt | #undef strxvfmt | ||||||
|  |  | ||||||
|  | #define T(x) QSE_MT(x) | ||||||
|  | #define char_t qse_mchar_t | ||||||
|  | #define buf_t mbuf_t | ||||||
|  | #define fmtout_t qse_mfmtout_t | ||||||
|  | #define fmtout qse_mfmtout | ||||||
|  | #define put_char_null put_mchar_null | ||||||
|  | #define put_char put_mchar_strict | ||||||
|  | #define conv_char wcs_to_mbs | ||||||
|  | #define strfmt qse_mbsfmts | ||||||
|  | #define strxfmt qse_mbsxfmts | ||||||
|  | #define strvfmt qse_mbsvfmts | ||||||
|  | #define strxvfmt qse_mbsxvfmts | ||||||
|  | #include "str-fmt.h" | ||||||
|  |  | ||||||
|  | /* ----------------------------------- */ | ||||||
|  |  | ||||||
|  | #undef T | ||||||
|  | #undef char_t | ||||||
|  | #undef buf_t | ||||||
|  | #undef fmtout_t | ||||||
|  | #undef fmtout | ||||||
|  | #undef put_char_null | ||||||
|  | #undef put_char | ||||||
|  | #undef conv_char | ||||||
|  | #undef strfmt | ||||||
|  | #undef strxfmt | ||||||
|  | #undef strvfmt | ||||||
|  | #undef strxvfmt | ||||||
|  |  | ||||||
| #define T(x) QSE_WT(x) | #define T(x) QSE_WT(x) | ||||||
| #define char_t qse_wchar_t | #define char_t qse_wchar_t | ||||||
| #define buf_t wbuf_t | #define buf_t wbuf_t | ||||||
| @ -149,3 +207,31 @@ static int mbs_to_wcs ( | |||||||
| #define strxvfmt qse_wcsxvfmt | #define strxvfmt qse_wcsxvfmt | ||||||
| #include "str-fmt.h" | #include "str-fmt.h" | ||||||
|  |  | ||||||
|  | /* ----------------------------------- */ | ||||||
|  |  | ||||||
|  | #undef T | ||||||
|  | #undef char_t | ||||||
|  | #undef buf_t | ||||||
|  | #undef fmtout_t | ||||||
|  | #undef fmtout | ||||||
|  | #undef put_char_null | ||||||
|  | #undef put_char | ||||||
|  | #undef conv_char | ||||||
|  | #undef strfmt | ||||||
|  | #undef strxfmt | ||||||
|  | #undef strvfmt | ||||||
|  | #undef strxvfmt | ||||||
|  |  | ||||||
|  | #define T(x) QSE_WT(x) | ||||||
|  | #define char_t qse_wchar_t | ||||||
|  | #define buf_t wbuf_t | ||||||
|  | #define fmtout_t qse_wfmtout_t | ||||||
|  | #define fmtout qse_wfmtout | ||||||
|  | #define put_char_null put_wchar_null | ||||||
|  | #define put_char put_wchar_strict | ||||||
|  | #define conv_char mbs_to_wcs | ||||||
|  | #define strfmt qse_wcsfmts | ||||||
|  | #define strxfmt qse_wcsxfmts | ||||||
|  | #define strvfmt qse_wcsvfmts | ||||||
|  | #define strxvfmt qse_wcsxvfmts | ||||||
|  | #include "str-fmt.h" | ||||||
|  | |||||||
| @ -24,11 +24,6 @@ | |||||||
| #include <qse/cmn/htb.h> | #include <qse/cmn/htb.h> | ||||||
| #include "../cmn/mem.h" | #include "../cmn/mem.h" | ||||||
|  |  | ||||||
| #include <stdio.h> /* for snprintf. TODO: remove this. */ |  | ||||||
| #if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) |  | ||||||
| #	define snprintf _snprintf  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| int qse_comparehttpversions ( | int qse_comparehttpversions ( | ||||||
| 	const qse_http_version_t* v1, | 	const qse_http_version_t* v1, | ||||||
| 	const qse_http_version_t* v2) | 	const qse_http_version_t* v2) | ||||||
| @ -378,9 +373,7 @@ qse_mchar_t* qse_fmthttptime ( | |||||||
|  |  | ||||||
| 	qse_gmtime (nt, &bt); | 	qse_gmtime (nt, &bt); | ||||||
|  |  | ||||||
| /* TODO: avoid using snprintf () */ | 	qse_mbsxfmt ( | ||||||
|  |  | ||||||
| 	snprintf ( |  | ||||||
| 		buf, bufsz, | 		buf, bufsz, | ||||||
| 		QSE_MT("%s, %d %s %d %02d:%02d:%02d GMT"), | 		QSE_MT("%s, %d %s %d %02d:%02d:%02d GMT"), | ||||||
| 		wday_name[bt.wday].s, | 		wday_name[bt.wday].s, | ||||||
|  | |||||||
| @ -35,11 +35,6 @@ | |||||||
| #	include "../cmn/syscall.h" | #	include "../cmn/syscall.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <stdio.h> /* TODO: remove this */ |  | ||||||
| #if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) |  | ||||||
| #	define snprintf _snprintf  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| typedef struct task_cgi_arg_t task_cgi_arg_t; | typedef struct task_cgi_arg_t task_cgi_arg_t; | ||||||
| struct task_cgi_arg_t  | struct task_cgi_arg_t  | ||||||
| { | { | ||||||
| @ -238,27 +233,19 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req) | |||||||
|  |  | ||||||
| 	if (req->attr.status) | 	if (req->attr.status) | ||||||
| 	{ | 	{ | ||||||
| 		qse_mchar_t buf[128]; |  | ||||||
| 		int nstatus; | 		int nstatus; | ||||||
| 		qse_mchar_t* endptr; | 		qse_mchar_t* endptr; | ||||||
|  |  | ||||||
| /* TODO: check the syntax of status value??? if not numeric??? */ | /* TODO: check the syntax of status value??? if not numeric??? */ | ||||||
| 		QSE_MBSTONUM (nstatus, req->attr.status, &endptr, 10); | 		QSE_MBSTONUM (nstatus, req->attr.status, &endptr, 10); | ||||||
|  |  | ||||||
| 		snprintf (buf, QSE_COUNTOF(buf),  |  | ||||||
| 			QSE_MT("HTTP/%d.%d %d "), |  | ||||||
| 			cgi->version.major,  |  | ||||||
| 			cgi->version.minor,  |  | ||||||
| 			nstatus |  | ||||||
| 		); |  | ||||||
|  |  | ||||||
| 		/*  | 		/*  | ||||||
| 		Would it need this kind of extra work? | 		Would it need this kind of extra work? | ||||||
| 		while (QSE_ISMSPACE(*endptr)) endptr++; | 		while (QSE_ISMSPACE(*endptr)) endptr++; | ||||||
| 		if (*endptr == QSE_MT('\0')) .... | 		if (*endptr == QSE_MT('\0')) .... | ||||||
| 		*/ | 		*/ | ||||||
|  |  | ||||||
| 		if (qse_mbs_cat (cgi->res, buf) == (qse_size_t)-1 || | 		if (qse_mbs_fcat (cgi->res, QSE_MT("HTTP/%d.%d %d "), cgi->version.major, cgi->version.minor, nstatus) == (qse_size_t)-1 || | ||||||
| 		    qse_mbs_cat (cgi->res, endptr) == (qse_size_t)-1 || | 		    qse_mbs_cat (cgi->res, endptr) == (qse_size_t)-1 || | ||||||
| 		    qse_mbs_cat (cgi->res, QSE_MT("\r\n")) == (qse_size_t)-1)  | 		    qse_mbs_cat (cgi->res, QSE_MT("\r\n")) == (qse_size_t)-1)  | ||||||
| 		{ | 		{ | ||||||
| @ -269,16 +256,12 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req) | |||||||
| 	else  | 	else  | ||||||
| 	{ | 	{ | ||||||
| 		const qse_htre_hdrval_t* location; | 		const qse_htre_hdrval_t* location; | ||||||
| 		qse_mchar_t buf[128]; |  | ||||||
|  |  | ||||||
| 		location = qse_htre_getheaderval (req, QSE_MT("Location")); | 		location = qse_htre_getheaderval (req, QSE_MT("Location")); | ||||||
| 		if (location) | 		if (location) | ||||||
| 		{ | 		{ | ||||||
| 			snprintf (buf, QSE_COUNTOF(buf), | 			if (qse_mbs_fcat (cgi->res, QSE_MT("HTTP/%d.%d 301 Moved Permanently\r\n"), | ||||||
| 				QSE_MT("HTTP/%d.%d 301 Moved Permanently\r\n"), | 			                  cgi->version.major, cgi->version.minor) == (qse_size_t)-1)  | ||||||
| 				cgi->version.major, cgi->version.minor |  | ||||||
| 			); |  | ||||||
| 			if (qse_mbs_cat (cgi->res, buf) == (qse_size_t)-1)  |  | ||||||
| 			{ | 			{ | ||||||
| 				cgi->httpd->errnum = QSE_HTTPD_ENOMEM; | 				cgi->httpd->errnum = QSE_HTTPD_ENOMEM; | ||||||
| 				return -1; | 				return -1; | ||||||
| @ -289,11 +272,8 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req) | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			snprintf (buf, QSE_COUNTOF(buf), | 			if (qse_mbs_fcat (cgi->res, QSE_MT("HTTP/%d.%d 200 OK\r\n"), | ||||||
| 				QSE_MT("HTTP/%d.%d 200 OK\r\n"), | 			                  cgi->version.major, cgi->version.minor) == (qse_size_t)-1)  | ||||||
| 				cgi->version.major, cgi->version.minor |  | ||||||
| 			); |  | ||||||
| 			if (qse_mbs_cat (cgi->res, buf) == (qse_size_t)-1)  |  | ||||||
| 			{ | 			{ | ||||||
| 				cgi->httpd->errnum = QSE_HTTPD_ENOMEM; | 				cgi->httpd->errnum = QSE_HTTPD_ENOMEM; | ||||||
| 				return -1; | 				return -1; | ||||||
| @ -467,7 +447,7 @@ static int cgi_add_env ( | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	qse_env_insertmbs (env, QSE_MT("GATEWAY_INTERFACE"), QSE_MT("CGI/1.1")); | 	qse_env_insertmbs (env, QSE_MT("GATEWAY_INTERFACE"), QSE_MT("CGI/1.1")); | ||||||
| 	snprintf (buf, QSE_COUNTOF(buf), QSE_MT("HTTP/%d.%d"), (int)v->major, (int)v->minor); | 	qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("HTTP/%d.%d"), (int)v->major, (int)v->minor); | ||||||
| 	qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), buf); | 	qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), buf); | ||||||
|  |  | ||||||
| 	qse_env_insertmbs (env, QSE_MT("SCRIPT_FILENAME"), path); | 	qse_env_insertmbs (env, QSE_MT("SCRIPT_FILENAME"), path); | ||||||
|  | |||||||
| @ -23,11 +23,6 @@ | |||||||
| #include <qse/cmn/str.h> | #include <qse/cmn/str.h> | ||||||
| #include <qse/cmn/fmt.h> | #include <qse/cmn/fmt.h> | ||||||
|  |  | ||||||
| #include <stdio.h> /* TODO: remove this */ |  | ||||||
| #if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) |  | ||||||
| #	define snprintf _snprintf  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| typedef struct task_dir_t task_dir_t; | typedef struct task_dir_t task_dir_t; | ||||||
| struct task_dir_t | struct task_dir_t | ||||||
| { | { | ||||||
| @ -141,14 +136,14 @@ static void fill_chunk_length (task_dseg_t* ctx) | |||||||
| 	while (ctx->buf[ctx->bufpos] == QSE_MT(' ')) ctx->bufpos++; | 	while (ctx->buf[ctx->bufpos] == QSE_MT(' ')) ctx->bufpos++; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int format_dirent ( | static qse_size_t format_dirent ( | ||||||
| 	qse_httpd_t* httpd,  | 	qse_httpd_t* httpd,  | ||||||
| 	qse_httpd_client_t* client,  | 	qse_httpd_client_t* client,  | ||||||
| 	const qse_httpd_dirent_t* dirent, | 	const qse_httpd_dirent_t* dirent, | ||||||
| 	qse_mchar_t* buf, int bufsz) | 	qse_mchar_t* buf, int bufsz) | ||||||
| { | { | ||||||
| /* TODO: page encoding?? utf-8??? or derive name from cmgr or current locale??? */ | /* TODO: page encoding?? utf-8??? or derive name from cmgr or current locale??? */ | ||||||
| 	int n; | 	qse_size_t x; | ||||||
|  |  | ||||||
| 	qse_mchar_t* encname; | 	qse_mchar_t* encname; | ||||||
| 	qse_mchar_t* escname; | 	qse_mchar_t* escname; | ||||||
| @ -176,9 +171,9 @@ static int format_dirent ( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	qse_localtime (&dirent->stat.mtime, &bt); | 	qse_localtime (&dirent->stat.mtime, &bt); | ||||||
| 	snprintf (tmbuf, QSE_COUNTOF(tmbuf), | 	qse_mbsxfmt (tmbuf, QSE_COUNTOF(tmbuf), | ||||||
| 		QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"), | 		QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"), | ||||||
|         		bt.year + QSE_BTIME_YEAR_BASE, bt.mon + 1, bt.mday, | 		bt.year + QSE_BTIME_YEAR_BASE, bt.mon + 1, bt.mday, | ||||||
| 		bt.hour, bt.min, bt.sec); | 		bt.hour, bt.min, bt.sec); | ||||||
|  |  | ||||||
| 	if (dirent->stat.isdir) | 	if (dirent->stat.isdir) | ||||||
| @ -193,7 +188,7 @@ static int format_dirent ( | |||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	n = snprintf ( | 	x = qse_mbsxfmts ( | ||||||
| 		buf, bufsz, | 		buf, bufsz, | ||||||
| 		QSE_MT("<tr><td class='name'><a href='%s%s' class='%s'>%s%s</a></td><td class='time'>%s</td><td class='size'>%s</td></tr>\n"), | 		QSE_MT("<tr><td class='name'><a href='%s%s' class='%s'>%s%s</a></td><td class='time'>%s</td><td class='size'>%s</td></tr>\n"), | ||||||
| 		encname, | 		encname, | ||||||
| @ -207,28 +202,24 @@ static int format_dirent ( | |||||||
| 	if (escname != dirent->name) qse_httpd_freemem (httpd, escname); | 	if (escname != dirent->name) qse_httpd_freemem (httpd, escname); | ||||||
| 	if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname); | 	if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname); | ||||||
|  |  | ||||||
| 	if (n <= -1 || n >= bufsz) | 	if (x == (qse_size_t)-1) httpd->errnum = QSE_HTTPD_ENOBUF; | ||||||
| 	{ | 	return x; | ||||||
| 		httpd->errnum = QSE_HTTPD_ENOBUF; |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return n; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static int add_footer (qse_httpd_t* httpd, qse_httpd_client_t* client, task_dseg_t* ctx) | static int add_footer (qse_httpd_t* httpd, qse_httpd_client_t* client, task_dseg_t* ctx) | ||||||
| { | { | ||||||
| 	int x, rem; | 	qse_size_t x; | ||||||
|  | 	int rem; | ||||||
|  |  | ||||||
| 	rem = ctx->chunked? (ctx->buflen - 5): ctx->buflen; | 	rem = ctx->chunked? (ctx->bufrem - 5): ctx->bufrem; | ||||||
| 	if (rem < 1) | 	if (rem < 1) | ||||||
| 	{ | 	{ | ||||||
| 		httpd->errnum = QSE_HTTPD_ENOBUF; | 		httpd->errnum = QSE_HTTPD_ENOBUF; | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	x = snprintf (&ctx->buf[ctx->buflen], rem, QSE_MT("</table></div>\n<div class='footer'>%s</div>\n</body></html>"), ctx->foot.ptr); | 	x = qse_mbsxfmts (&ctx->buf[ctx->buflen], rem, QSE_MT("</table></div>\n<div class='footer'>%s</div>\n</body></html>"), ctx->foot.ptr); | ||||||
| 	if (x <= -1 || x >= rem)  | 	if (x == (qse_size_t)-1)  | ||||||
| 	{ | 	{ | ||||||
| 		httpd->errnum = QSE_HTTPD_ENOBUF; | 		httpd->errnum = QSE_HTTPD_ENOBUF; | ||||||
| 		return -1; | 		return -1; | ||||||
| @ -257,7 +248,7 @@ static int task_main_dseg ( | |||||||
| { | { | ||||||
| 	task_dseg_t* ctx = (task_dseg_t*)task->ctx; | 	task_dseg_t* ctx = (task_dseg_t*)task->ctx; | ||||||
| 	qse_ssize_t n; | 	qse_ssize_t n; | ||||||
| 	int x; | 	qse_size_t x; | ||||||
|  |  | ||||||
| 	if (ctx->bufpos < ctx->buflen)  | 	if (ctx->bufpos < ctx->buflen)  | ||||||
| 	{ | 	{ | ||||||
| @ -335,17 +326,14 @@ static int task_main_dseg ( | |||||||
| 		qpath_esc = qse_httpd_escapehtml (httpd, ctx->qpath.ptr); | 		qpath_esc = qse_httpd_escapehtml (httpd, ctx->qpath.ptr); | ||||||
| 		if (qpath_esc == QSE_NULL) return -1; | 		if (qpath_esc == QSE_NULL) return -1; | ||||||
|  |  | ||||||
| 		x = snprintf (&ctx->buf[ctx->buflen], ctx->bufrem, | 		x = qse_mbsxfmts (&ctx->buf[ctx->buflen], ctx->bufrem, | ||||||
| 			QSE_MT("<html><head>%s</head>\n<body>\n<div class='header'>%s</div>\n<div class='body'><table>%s"), ctx->head.ptr, qpath_esc, | 			QSE_MT("<html><head>%s</head>\n<body>\n<div class='header'>%s</div>\n<div class='body'><table>%s"), ctx->head.ptr, qpath_esc, | ||||||
| 			(is_root? QSE_MT(""): QSE_MT("<tr><td class='name'><a href='../' class='dir'>..</a></td><td class='time'></td><td class='size'></td></tr>\n")) | 			(is_root? QSE_MT(""): QSE_MT("<tr><td class='name'><a href='../' class='dir'>..</a></td><td class='time'></td><td class='size'></td></tr>\n")) | ||||||
| 		); | 		); | ||||||
|  |  | ||||||
| 		if (qpath_esc != ctx->qpath.ptr) qse_httpd_freemem (httpd, qpath_esc); | 		if (qpath_esc != ctx->qpath.ptr) qse_httpd_freemem (httpd, qpath_esc); | ||||||
|  |  | ||||||
| #if 0 | 		if (x == (qse_size_t)-1) | ||||||
| 		if (x <= -1) |  | ||||||
| #endif |  | ||||||
| 		if (x <= -1 || x >= ctx->bufrem) |  | ||||||
| 		{ | 		{ | ||||||
| 			/* return an error if the buffer is too small to  | 			/* return an error if the buffer is too small to  | ||||||
| 			 * hold the header(httpd->errnum == QSE_HTTPD_ENOBUF). | 			 * hold the header(httpd->errnum == QSE_HTTPD_ENOBUF). | ||||||
| @ -371,7 +359,7 @@ static int task_main_dseg ( | |||||||
| 	else  | 	else  | ||||||
| 	{ | 	{ | ||||||
| 		if (httpd->opt.scb.dir.read (httpd, ctx->handle, &ctx->dent) <= 0) | 		if (httpd->opt.scb.dir.read (httpd, ctx->handle, &ctx->dent) <= 0) | ||||||
| 			ctx->state |= DIRENT_NOMORE;	 | 			ctx->state |= DIRENT_NOMORE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	do | 	do | ||||||
| @ -391,15 +379,14 @@ static int task_main_dseg ( | |||||||
| 				ctx->state |= FOOTER_PENDING; | 				ctx->state |= FOOTER_PENDING; | ||||||
| 			} | 			} | ||||||
| 			else if (ctx->chunked) fill_chunk_length (ctx); | 			else if (ctx->chunked) fill_chunk_length (ctx); | ||||||
| 			break;	 | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 		if (qse_mbscmp (ctx->dent.name, QSE_MT(".")) != 0 && | 		if (qse_mbscmp (ctx->dent.name, QSE_MT(".")) != 0 && | ||||||
| 		    qse_mbscmp (ctx->dent.name, QSE_MT("..")) != 0) | 		    qse_mbscmp (ctx->dent.name, QSE_MT("..")) != 0) | ||||||
| 		{ | 		{ | ||||||
| 			x = format_dirent (httpd, client, &ctx->dent, &ctx->buf[ctx->buflen], ctx->bufrem);  | 			x = format_dirent (httpd, client, &ctx->dent, &ctx->buf[ctx->buflen], ctx->bufrem);  | ||||||
| 			if (x <= -1) | 			if (x == (qse_size_t)-1) | ||||||
| 			{ | 			{ | ||||||
| 				/* buffer not large enough to hold this entry */ | 				/* buffer not large enough to hold this entry */ | ||||||
| 				if (ctx->dcount <= 0)  | 				if (ctx->dcount <= 0)  | ||||||
| @ -445,7 +432,7 @@ send_dirlist: | |||||||
| 	if (n <= -1) return -1; | 	if (n <= -1) return -1; | ||||||
|  |  | ||||||
| 	/* NOTE if (n == 0), it will enter an infinite loop */ | 	/* NOTE if (n == 0), it will enter an infinite loop */ | ||||||
| 		 |  | ||||||
| 	ctx->bufpos += n; | 	ctx->bufpos += n; | ||||||
| 	return (ctx->bufpos < ctx->buflen || (ctx->state & FOOTER_PENDING) || !(ctx->state & DIRENT_NOMORE))? 1: 0; | 	return (ctx->bufpos < ctx->buflen || (ctx->state & FOOTER_PENDING) || !(ctx->state & DIRENT_NOMORE))? 1: 0; | ||||||
| } | } | ||||||
| @ -669,7 +656,7 @@ qse_httpd_task_t* qse_httpd_entaskdir ( | |||||||
| 				status = (httpd->errnum == QSE_HTTPD_ENOENT)? 404: | 				status = (httpd->errnum == QSE_HTTPD_ENOENT)? 404: | ||||||
| 				         (httpd->errnum == QSE_HTTPD_EACCES)? 403: 500; | 				         (httpd->errnum == QSE_HTTPD_EACCES)? 403: 500; | ||||||
| 			} | 			} | ||||||
| 				 |  | ||||||
| 			return qse_httpd_entaskerr (httpd, client, pred, status, req); | 			return qse_httpd_entaskerr (httpd, client, pred, status, req); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | |||||||
| @ -107,11 +107,6 @@ | |||||||
| #	include <openssl/engine.h> | #	include <openssl/engine.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <stdio.h> /* TODO: remove this */ |  | ||||||
| #if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) |  | ||||||
| #	define snprintf _snprintf  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| typedef struct server_xtn_t server_xtn_t; | typedef struct server_xtn_t server_xtn_t; | ||||||
| struct server_xtn_t | struct server_xtn_t | ||||||
| { | { | ||||||
| @ -2142,8 +2137,6 @@ if (qse_htre_getcontentlen(req) > 0) | |||||||
| 			 * | 			 * | ||||||
| 			 * NOTE: CONNECT is implemented to ignore many headers like | 			 * NOTE: CONNECT is implemented to ignore many headers like | ||||||
| 			 *       'Expect: 100-continue' and 'Connection: keep-alive'. */ | 			 *       'Expect: 100-continue' and 'Connection: keep-alive'. */ | ||||||
|  |  | ||||||
| /* TODO: CHECK if CONNECT is allowed ... */ |  | ||||||
| 			qse_httpd_discardcontent (httpd, req); | 			qse_httpd_discardcontent (httpd, req); | ||||||
| 		} | 		} | ||||||
| 		else  | 		else  | ||||||
| @ -2272,7 +2265,7 @@ static int poke_request ( | |||||||
| static int format_error ( | static int format_error ( | ||||||
| 	qse_httpd_t* httpd, qse_httpd_client_t* client, int code, qse_mchar_t* buf, int bufsz) | 	qse_httpd_t* httpd, qse_httpd_client_t* client, int code, qse_mchar_t* buf, int bufsz) | ||||||
| { | { | ||||||
| 	int n; | 	qse_size_t n; | ||||||
| 	server_xtn_t* server_xtn; | 	server_xtn_t* server_xtn; | ||||||
| 	const qse_mchar_t* head, * foot, * msg; | 	const qse_mchar_t* head, * foot, * msg; | ||||||
|  |  | ||||||
| @ -2286,17 +2279,16 @@ static int format_error ( | |||||||
|  |  | ||||||
| 	msg = qse_httpstatustombs(code); | 	msg = qse_httpstatustombs(code); | ||||||
|  |  | ||||||
| /* TODO: use my own version of snprintf replacement */ | 	n = qse_mbsxfmts (buf, bufsz, | ||||||
| 	n = snprintf (buf, bufsz, |  | ||||||
| 		QSE_MT("<html><head>%s<title>%s</title></head><body><div class='header'>HTTP ERROR</div><div class='body'>%d %s</div><div class='footer'>%s</div></body></html>"),  | 		QSE_MT("<html><head>%s<title>%s</title></head><body><div class='header'>HTTP ERROR</div><div class='body'>%d %s</div><div class='footer'>%s</div></body></html>"),  | ||||||
| 		head, msg, code, msg, foot); | 		head, msg, code, msg, foot); | ||||||
| 	if (n < 0 || n >= bufsz)  | 	if (n == (qse_size_t)-1) | ||||||
| 	{ | 	{ | ||||||
| 		httpd->errnum = QSE_HTTPD_ENOBUF; | 		httpd->errnum = QSE_HTTPD_ENOBUF; | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return n; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void impede_httpd (qse_httpd_t* httpd) | static void impede_httpd (qse_httpd_t* httpd) | ||||||
|  | |||||||
| @ -199,7 +199,7 @@ qse_httpd_task_t* qse_httpd_entask_status ( | |||||||
| 		case 205: | 		case 205: | ||||||
| 		case 206: | 		case 206: | ||||||
| 			/* nothing to do */ | 			/* nothing to do */ | ||||||
| 			break;	 | 			break; | ||||||
|  |  | ||||||
| 		default: | 		default: | ||||||
| 			if (method != QSE_HTTP_HEAD && | 			if (method != QSE_HTTP_HEAD && | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user