added qse_isdriveabspath().
enhanced httpd to accept drive path as a doc root for win/os2
This commit is contained in:
		| @ -102,6 +102,10 @@ QSE_EXPORT void* qse_mux_getxtn ( | |||||||
| 	qse_mux_t* mux | 	qse_mux_t* mux | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_mux_errnum_t qse_mux_geterrnum ( | ||||||
|  | 	qse_mux_t* mux | ||||||
|  | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_mux_insert ( | QSE_EXPORT int qse_mux_insert ( | ||||||
| 	qse_mux_t*           mux, | 	qse_mux_t*           mux, | ||||||
| 	const qse_mux_evt_t* evt | 	const qse_mux_evt_t* evt | ||||||
|  | |||||||
| @ -99,6 +99,14 @@ QSE_EXPORT int qse_ismbsdrivepath ( | |||||||
| 	const qse_mchar_t* path | 	const qse_mchar_t* path | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The qse_ismbsdriveabspath() function determines if a path name is in the form | ||||||
|  |  * of a drive letter followed by a colon like A: and a path separator. | ||||||
|  |  */ | ||||||
|  | QSE_EXPORT int qse_ismbsdriveabspath ( | ||||||
|  | 	const qse_mchar_t* path | ||||||
|  | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The qse_ismbsdrivecurpath() function determines if a path name is in the form |  * The qse_ismbsdrivecurpath() function determines if a path name is in the form | ||||||
|  * of a drive letter followed by a colon like A:, without any trailing path. |  * of a drive letter followed by a colon like A:, without any trailing path. | ||||||
| @ -165,6 +173,14 @@ QSE_EXPORT int qse_iswcsdrivepath ( | |||||||
| 	const qse_wchar_t* path | 	const qse_wchar_t* path | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The qse_iswcsdriveabspath() function determines if a path name is in the form | ||||||
|  |  * of a drive letter followed by a colon like A: and a path separtor. | ||||||
|  |  */ | ||||||
|  | QSE_EXPORT int qse_iswcsdriveabspath ( | ||||||
|  | 	const qse_wchar_t* path | ||||||
|  | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The qse_iswcsdrivecurpath() function determines if a path name is in the form |  * The qse_iswcsdrivecurpath() function determines if a path name is in the form | ||||||
|  * of a drive letter followed by a colon like A:, without any trailing path. |  * of a drive letter followed by a colon like A:, without any trailing path. | ||||||
| @ -215,11 +231,13 @@ QSE_EXPORT qse_size_t qse_canonwcspath ( | |||||||
| #if defined(QSE_CHAR_IS_MCHAR) | #if defined(QSE_CHAR_IS_MCHAR) | ||||||
| #	define qse_isabspath(p)      qse_ismbsabspath(p) | #	define qse_isabspath(p)      qse_ismbsabspath(p) | ||||||
| #	define qse_isdrivepath(p)    qse_ismbsdrivepath(p) | #	define qse_isdrivepath(p)    qse_ismbsdrivepath(p) | ||||||
|  | #	define qse_isdriveabspath(p) qse_ismbsdriveabspath(p) | ||||||
| #	define qse_isdrivecurpath(p) qse_ismbsdrivecurpath(p) | #	define qse_isdrivecurpath(p) qse_ismbsdrivecurpath(p) | ||||||
| #	define qse_canonpath(p,c,f)  qse_canonmbspath(p,c,f) | #	define qse_canonpath(p,c,f)  qse_canonmbspath(p,c,f) | ||||||
| #else | #else | ||||||
| #	define qse_isabspath(p)      qse_iswcsabspath(p) | #	define qse_isabspath(p)      qse_iswcsabspath(p) | ||||||
| #	define qse_isdrivepath(p)    qse_iswcsdrivepath(p) | #	define qse_isdrivepath(p)    qse_iswcsdrivepath(p) | ||||||
|  | #	define qse_isdriveabspath(p) qse_iswcsdriveabspath(p) | ||||||
| #	define qse_isdrivecurpath(p) qse_iswcsdrivecurpath(p) | #	define qse_isdrivecurpath(p) qse_iswcsdrivecurpath(p) | ||||||
| #	define qse_canonpath(p,c,f)  qse_canonwcspath(p,c,f) | #	define qse_canonpath(p,c,f)  qse_canonwcspath(p,c,f) | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -49,7 +49,6 @@ enum qse_httpd_errnum_t | |||||||
| 	QSE_HTTPD_EAGAIN, | 	QSE_HTTPD_EAGAIN, | ||||||
| 	QSE_HTTPD_ENOBUF, | 	QSE_HTTPD_ENOBUF, | ||||||
|  |  | ||||||
| 	QSE_HTTPD_EIOMUX, |  | ||||||
| 	QSE_HTTPD_EDISCON, /* client disconnnected */ | 	QSE_HTTPD_EDISCON, /* client disconnnected */ | ||||||
| 	QSE_HTTPD_EBADREQ, /* bad request */ | 	QSE_HTTPD_EBADREQ, /* bad request */ | ||||||
| 	QSE_HTTPD_ETASK | 	QSE_HTTPD_ETASK | ||||||
|  | |||||||
| @ -363,14 +363,17 @@ void* qse_mux_getxtn (qse_mux_t* mux) | |||||||
| 	return QSE_XTN (mux); | 	return QSE_XTN (mux); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | qse_mux_errnum_t qse_mux_geterrnum (qse_mux_t* mux) | ||||||
|  | { | ||||||
|  | 	return mux->errnum; | ||||||
|  | } | ||||||
|  |  | ||||||
| #define ALIGN_TO(num,align) ((((num) + (align) - 1) / (align)) * (align)) | #define ALIGN_TO(num,align) ((((num) + (align) - 1) / (align)) * (align)) | ||||||
|  |  | ||||||
| int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt) | int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt) | ||||||
| { | { | ||||||
| #if defined(__OS2__) | #if defined(__OS2__) | ||||||
|  |  | ||||||
| if (evt) qse_printf (QSE_T("INSERTING HANDLE %d\n"), (int)evt->hnd); |  | ||||||
| else qse_printf (QSE_T("WHAT..... NULL\n")); |  | ||||||
| 	if (evt->hnd >= mux->me.ubound) | 	if (evt->hnd >= mux->me.ubound) | ||||||
| 	{ | 	{ | ||||||
| 		qse_mux_evt_t** tmp; | 		qse_mux_evt_t** tmp; | ||||||
| @ -564,6 +567,7 @@ int qse_mux_delete (qse_mux_t* mux, const qse_mux_evt_t* evt) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mevt->hnd = -1; | 	mevt->hnd = -1; | ||||||
|  | 	mevt->mask = 0; | ||||||
| 	mux->size--; | 	mux->size--; | ||||||
| 	return 0;	 | 	return 0;	 | ||||||
|  |  | ||||||
| @ -608,6 +612,7 @@ int qse_mux_delete (qse_mux_t* mux, const qse_mux_evt_t* evt) | |||||||
|  |  | ||||||
| done: | done: | ||||||
| 	mevt->hnd = -1; | 	mevt->hnd = -1; | ||||||
|  | 	mevt->mask = 0; | ||||||
| 	mux->size--; | 	mux->size--; | ||||||
| 	return 0;	 | 	return 0;	 | ||||||
|  |  | ||||||
| @ -652,15 +657,13 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout) | |||||||
| 	for (i = 0; i < mux->me.ubound; i++) | 	for (i = 0; i < mux->me.ubound; i++) | ||||||
| 	{ | 	{ | ||||||
| 		evt = mux->me.ptr[i]; | 		evt = mux->me.ptr[i]; | ||||||
| 		if (evt && (evt->mask & QSE_MUX_IN)) | 		if (evt && (evt->mask & QSE_MUX_IN)) mux->fdarr[count++] = evt->hnd; | ||||||
| 			mux->fdarr[count++] = evt->hnd; |  | ||||||
| 	} | 	} | ||||||
| 	rcount = count; | 	rcount = count; | ||||||
| 	for (i = 0; i < mux->me.ubound; i++) | 	for (i = 0; i < mux->me.ubound; i++) | ||||||
| 	{ | 	{ | ||||||
| 		evt = mux->me.ptr[i]; | 		evt = mux->me.ptr[i]; | ||||||
| 		if (evt && (evt->mask & QSE_MUX_OUT))  | 		if (evt && (evt->mask & QSE_MUX_OUT)) mux->fdarr[count++] = evt->hnd; | ||||||
| 			mux->fdarr[count++] = evt->hnd; |  | ||||||
| 	} | 	} | ||||||
| 	wcount = count - rcount; | 	wcount = count - rcount; | ||||||
|  |  | ||||||
| @ -677,22 +680,21 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout) | |||||||
|  |  | ||||||
| 		for (i = 0; i < count; i++) | 		for (i = 0; i < count; i++) | ||||||
| 		{ | 		{ | ||||||
| 			evt = mux->me.ptr[i]; | 			if (mux->fdarr[i] == -1) continue; | ||||||
| 			if (!evt || evt->hnd != i || mux->fdarr[i] == -1) continue; |  | ||||||
|  |  | ||||||
| 			QSE_MEMCPY (&xevt, evt, QSE_SIZEOF(xevt)); | 			evt = mux->me.ptr[mux->fdarr[i]]; | ||||||
|  | 			if (!evt || evt->hnd != mux->fdarr[i]) continue; | ||||||
|  |  | ||||||
| 			xevt.mask = 0; | 			xevt = *evt; | ||||||
| 			if ((evt->mask & QSE_MUX_IN) && i < rcount) |  | ||||||
| 				xevt.mask |= QSE_MUX_IN; |  | ||||||
| 			if ((evt->mask & QSE_MUX_OUT) && i >= rcount) |  | ||||||
| 				xevt.mask |= QSE_MUX_OUT; |  | ||||||
|  |  | ||||||
| 			if (xevt.mask > 0) mux->evtfun (mux, &xevt); | 			/* due to the way i check 'fdarr' , it can't have | ||||||
|  | 			 * both IN and OUT at the same time. they are  | ||||||
|  | 			 * triggered separately */ | ||||||
|  | 			xevt.mask = (i < rcount)? QSE_MUX_IN: QSE_MUX_OUT; | ||||||
|  | 			mux->evtfun (mux, &xevt); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	return n; | 	return n; | ||||||
|  |  | ||||||
| #elif defined(USE_SELECT) | #elif defined(USE_SELECT) | ||||||
| @ -728,8 +730,7 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout) | |||||||
| 			evt = mux->me.ptr[i]; | 			evt = mux->me.ptr[i]; | ||||||
| 			if (!evt || evt->hnd != i) continue; | 			if (!evt || evt->hnd != i) continue; | ||||||
|  |  | ||||||
| 			QSE_MEMCPY (&xevt, evt, QSE_SIZEOF(xevt)); | 			xevt = *evt; | ||||||
|  |  | ||||||
| 			xevt.mask = 0; | 			xevt.mask = 0; | ||||||
| 			if ((evt->mask & QSE_MUX_IN) &&  | 			if ((evt->mask & QSE_MUX_IN) &&  | ||||||
| 			    FD_ISSET(evt->hnd, &mux->tmprset)) xevt.mask |= QSE_MUX_IN; | 			    FD_ISSET(evt->hnd, &mux->tmprset)) xevt.mask |= QSE_MUX_IN; | ||||||
| @ -764,8 +765,7 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout) | |||||||
|  |  | ||||||
| 		evt = mux->ee.ptr[i].data.ptr; | 		evt = mux->ee.ptr[i].data.ptr; | ||||||
|  |  | ||||||
| 		QSE_MEMCPY (&xevt, evt, QSE_SIZEOF(xevt)); | 		xevt = *evt; | ||||||
|  |  | ||||||
| 		xevt.mask = 0; | 		xevt.mask = 0; | ||||||
| 		if (mux->ee.ptr[i].events & EPOLLIN) xevt.mask |= QSE_MUX_IN; | 		if (mux->ee.ptr[i].events & EPOLLIN) xevt.mask |= QSE_MUX_IN; | ||||||
| 		if (mux->ee.ptr[i].events & EPOLLOUT) xevt.mask |= QSE_MUX_OUT; | 		if (mux->ee.ptr[i].events & EPOLLOUT) xevt.mask |= QSE_MUX_OUT; | ||||||
|  | |||||||
| @ -53,6 +53,14 @@ int qse_ismbsdrivepath (const qse_mchar_t* path) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int qse_ismbsdriveabspath (const qse_mchar_t* path) | ||||||
|  | { | ||||||
|  | #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||||
|  | 	if (IS_MDRIVE(path) && IS_MSEP(path[2])) return 1; | ||||||
|  | #endif | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| int qse_ismbsdrivecurpath (const qse_mchar_t* path) | int qse_ismbsdrivecurpath (const qse_mchar_t* path) | ||||||
| { | { | ||||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||||
| @ -360,6 +368,14 @@ int qse_iswcsdrivepath (const qse_wchar_t* path) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int qse_iswcsdriveabspath (const qse_wchar_t* path) | ||||||
|  | { | ||||||
|  | #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||||
|  | 	if (IS_WDRIVE(path) && IS_WSEP(path[2])) return 1; | ||||||
|  | #endif | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| int qse_iswcsdrivecurpath (const qse_wchar_t* path) | int qse_iswcsdrivecurpath (const qse_wchar_t* path) | ||||||
| { | { | ||||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||||
|  | |||||||
| @ -241,6 +241,35 @@ static qse_httpd_errnum_t syserr_to_errnum (int e) | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static qse_httpd_errnum_t muxerr_to_errnum (qse_mux_errnum_t e) | ||||||
|  | { | ||||||
|  |      switch (e) | ||||||
|  |      { | ||||||
|  |           case QSE_MUX_ENOMEM: | ||||||
|  |                return QSE_HTTPD_ENOMEM; | ||||||
|  |  | ||||||
|  |           case QSE_MUX_EINVAL: | ||||||
|  |                return QSE_HTTPD_EINVAL; | ||||||
|  |  | ||||||
|  |           case QSE_MUX_EACCES: | ||||||
|  |                return QSE_HTTPD_EACCES; | ||||||
|  |  | ||||||
|  |           case QSE_MUX_ENOENT: | ||||||
|  |                return QSE_HTTPD_ENOENT; | ||||||
|  |  | ||||||
|  |           case QSE_MUX_EEXIST: | ||||||
|  |                return QSE_HTTPD_EEXIST; | ||||||
|  |  | ||||||
|  |           case QSE_MUX_EINTR: | ||||||
|  |                return QSE_HTTPD_EINTR; | ||||||
|  |  | ||||||
|  |           default: | ||||||
|  |                return QSE_HTTPD_ESYSERR; | ||||||
|  |      } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------- */ | /* ------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| #define MAX_SEND_SIZE 4096 | #define MAX_SEND_SIZE 4096 | ||||||
| @ -891,9 +920,7 @@ static void* mux_open (qse_httpd_t* httpd, qse_httpd_muxcb_t cbfun) | |||||||
| 	mux = qse_mux_open (httpd->mmgr, QSE_SIZEOF(*xtn), dispatch_muxcb, 256); | 	mux = qse_mux_open (httpd->mmgr, QSE_SIZEOF(*xtn), dispatch_muxcb, 256); | ||||||
| 	if (!mux) | 	if (!mux) | ||||||
| 	{ | 	{ | ||||||
| /* TODO  | 		qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR); | ||||||
| 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(mux)); |  | ||||||
| */ |  | ||||||
| 		return QSE_NULL; | 		return QSE_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -921,9 +948,7 @@ static int mux_addhnd ( | |||||||
|  |  | ||||||
| 	if (qse_mux_insert ((qse_mux_t*)vmux, &evt) <= -1) | 	if (qse_mux_insert ((qse_mux_t*)vmux, &evt) <= -1) | ||||||
| 	{ | 	{ | ||||||
| /* TODO  | 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(qse_mux_geterrnum((qse_mux_t*)vmux))); | ||||||
| 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(mux)); |  | ||||||
| */ |  | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -936,9 +961,7 @@ static int mux_delhnd (qse_httpd_t* httpd, void* vmux, qse_ubi_t handle) | |||||||
| 	evt.hnd = handle.i;	 | 	evt.hnd = handle.i;	 | ||||||
| 	if (qse_mux_delete ((qse_mux_t*)vmux, &evt) <= -1) | 	if (qse_mux_delete ((qse_mux_t*)vmux, &evt) <= -1) | ||||||
| 	{ | 	{ | ||||||
| /* TODO  | 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(qse_mux_geterrnum((qse_mux_t*)vmux))); | ||||||
| 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(mux)); |  | ||||||
| */ |  | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -948,9 +971,7 @@ static int mux_poll (qse_httpd_t* httpd, void* vmux, const qse_ntime_t* tmout) | |||||||
| { | { | ||||||
| 	if (qse_mux_poll ((qse_mux_t*)vmux, tmout) <= -1) | 	if (qse_mux_poll ((qse_mux_t*)vmux, tmout) <= -1) | ||||||
| 	{ | 	{ | ||||||
| /* TODO  | 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(qse_mux_geterrnum((qse_mux_t*)vmux))); | ||||||
| 		qse_httpd_seterrnum (httpd, muxerr_to_errnum(mux)); |  | ||||||
| */ |  | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -1021,9 +1042,6 @@ static int stat_file ( | |||||||
| 	WIN32_FIND_DATAA fdata; | 	WIN32_FIND_DATAA fdata; | ||||||
| 	ULARGE_INTEGER li; | 	ULARGE_INTEGER li; | ||||||
|  |  | ||||||
| 	/* fail if the path name contains a wilecard letter */ |  | ||||||
| 	if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 	if (path[0] == QSE_MT('/') && path[1] ==  QSE_MT('\0')) | 	if (path[0] == QSE_MT('/') && path[1] ==  QSE_MT('\0')) | ||||||
| 	{ | 	{ | ||||||
| 		/* the root directory won't work well with FindFirstFile().*/ | 		/* the root directory won't work well with FindFirstFile().*/ | ||||||
| @ -1035,6 +1053,9 @@ static int stat_file ( | |||||||
| 	{ | 	{ | ||||||
| 		/* TODO: hst->dev can be set to the drive letter's index. */ | 		/* TODO: hst->dev can be set to the drive letter's index. */ | ||||||
|  |  | ||||||
|  | 		/* fail if the path name contains a wilecard letter */ | ||||||
|  | 		if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1; | ||||||
|  |  | ||||||
| 		fh = FindFirstFileA (path, &fdata); | 		fh = FindFirstFileA (path, &fdata); | ||||||
| 		if (fh == INVALID_HANDLE_VALUE) return -1; | 		if (fh == INVALID_HANDLE_VALUE) return -1; | ||||||
|  |  | ||||||
| @ -1056,29 +1077,10 @@ static int stat_file ( | |||||||
|  |  | ||||||
| #elif defined(__OS2__) | #elif defined(__OS2__) | ||||||
| 	APIRET rc; | 	APIRET rc; | ||||||
| 	FILEFINDBUF3L ffb; |  | ||||||
| 	qse_btime_t bt; | 	qse_btime_t bt; | ||||||
| 	qse_ntime_t nt; | 	qse_ntime_t nt; | ||||||
|  |  | ||||||
| 	#if 0 | 	FILESTATUS3L ffb; | ||||||
| 	HDIR h; |  | ||||||
| 	ULONG count; |  | ||||||
|  |  | ||||||
| 	/* fail if the path name contains a wilecard letter */ |  | ||||||
| 	if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 	rc = DosFindFirst ( |  | ||||||
| 		path, |  | ||||||
| 		&h, |  | ||||||
| 		FILE_DIRECTORY | FILE_READONLY, |  | ||||||
| 		&ffb, |  | ||||||
| 		QSE_SIZEOF(ffb), |  | ||||||
| 		&count, |  | ||||||
| 		FIL_STANDARDL); |  | ||||||
| 	if (rc != NO_ERROR) return -1; |  | ||||||
|  |  | ||||||
| 	DosFindClose (h); |  | ||||||
| 	#endif |  | ||||||
|  |  | ||||||
| 	rc = DosQueryPathInfo (path, FIL_STANDARDL, &ffb, QSE_SIZEOF(ffb)); | 	rc = DosQueryPathInfo (path, FIL_STANDARDL, &ffb, QSE_SIZEOF(ffb)); | ||||||
| 	if (rc != NO_ERROR) return -1; | 	if (rc != NO_ERROR) return -1; | ||||||
| @ -1987,7 +1989,7 @@ static int make_resource ( | |||||||
| 	qse_mchar_t* xpath;  | 	qse_mchar_t* xpath;  | ||||||
| 	qse_httpd_stat_t st; | 	qse_httpd_stat_t st; | ||||||
| 	qse_size_t i; | 	qse_size_t i; | ||||||
| 	int n; | 	int n, stx; | ||||||
|  |  | ||||||
| 	qpath = qse_htre_getqpath(req); | 	qpath = qse_htre_getqpath(req); | ||||||
|  |  | ||||||
| @ -2022,10 +2024,23 @@ auth_ok: | |||||||
| 	xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT], qpath); | 	xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT], qpath); | ||||||
| 	if (xpath == QSE_NULL) return -1; | 	if (xpath == QSE_NULL) return -1; | ||||||
|  |  | ||||||
| qse_printf (QSE_T(">>> check if [%hs] is a directory\n"), xpath); | 	stx = stat_file (httpd, xpath, &st, 0); | ||||||
| 	if (stat_file (httpd, xpath, &st, 0) >= 0 && st.isdir) | #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||||
|  | 	if (stx <= -1) | ||||||
|  | 	{ | ||||||
|  | 		/* these OS may fail if the path contains the trailing separator. | ||||||
|  | 		 * i work around it here */ | ||||||
|  | 		qse_size_t pl = qse_mbslen(xpath); | ||||||
|  | 		if (pl > 1 && xpath[pl - 1] == QSE_MT('/'))  | ||||||
|  | 		{ | ||||||
|  | 			xpath[pl-1] = QSE_MT('\0'); | ||||||
|  | 			stx = stat_file (httpd, xpath, &st, 0); | ||||||
|  | 			xpath[pl-1] = QSE_MT('/'); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  | 	if (stx >= 0 && st.isdir) | ||||||
| 	{ | 	{ | ||||||
| qse_printf (QSE_T(">>> [%hs] is a directory\n"), xpath); |  | ||||||
| 		/* it is a directory */ | 		/* it is a directory */ | ||||||
| 		if (server_xtn->cfg2.s.idxstd) | 		if (server_xtn->cfg2.s.idxstd) | ||||||
| 		{ | 		{ | ||||||
| @ -2056,11 +2071,9 @@ qse_printf (QSE_T(">>> [%hs] is a directory\n"), xpath); | |||||||
|  |  | ||||||
| 		target->type = QSE_HTTPD_RSRC_DIR; | 		target->type = QSE_HTTPD_RSRC_DIR; | ||||||
| 		target->u.dir.path = xpath; | 		target->u.dir.path = xpath; | ||||||
| qse_printf (QSE_T(">>> MADE DIREcTORY RESOURCE [%hs]\n"), xpath); |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| qse_printf (QSE_T(">>> [%hs] is a file\n"), xpath); |  | ||||||
| 	attempt_file: | 	attempt_file: | ||||||
| 		if (server_xtn->cfg2.s.cgistd) | 		if (server_xtn->cfg2.s.cgistd) | ||||||
| 		{ | 		{ | ||||||
| @ -2216,6 +2229,7 @@ qse_httpd_server_t* qse_httpd_attachserverstd ( | |||||||
|  |  | ||||||
| 	if (!xuri.path.ptr) | 	if (!xuri.path.ptr) | ||||||
| 	{ | 	{ | ||||||
|  | 		/* the path part is not specified */ | ||||||
| #if defined(QSE_CHAR_IS_MCHAR) | #if defined(QSE_CHAR_IS_MCHAR) | ||||||
| 		xuri.path.ptr = QSE_MT("/"); | 		xuri.path.ptr = QSE_MT("/"); | ||||||
| #else | #else | ||||||
| @ -2236,11 +2250,17 @@ qse_httpd_server_t* qse_httpd_attachserverstd ( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #if defined(QSE_CHAR_IS_MCHAR) | #if defined(QSE_CHAR_IS_MCHAR) | ||||||
|  | 	if (qse_ismbsdriveabspath((const qse_mchar_t*)xuri.path.ptr + 1)) | ||||||
|  | 		server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_mbsxdup ((const qse_mchar_t*)xuri.path.ptr + 1, xuri.path.len - 1, httpd->mmgr); | ||||||
|  | 	else | ||||||
| 		server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_mbsxdup (xuri.path.ptr, xuri.path.len, httpd->mmgr); | 		server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_mbsxdup (xuri.path.ptr, xuri.path.len, httpd->mmgr); | ||||||
| 	if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM] = qse_mbsxdup (xuri.frag.ptr, xuri.frag.len, httpd->mmgr); | 	if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM] = qse_mbsxdup (xuri.frag.ptr, xuri.frag.len, httpd->mmgr); | ||||||
| 	ba.ptr = qse_mcstradup (tmp, &ba.len, httpd->mmgr); | 	ba.ptr = qse_mcstradup (tmp, &ba.len, httpd->mmgr); | ||||||
| 	 | 	 | ||||||
| #else | #else | ||||||
|  | 	if (qse_iswcsdriveabspath((const qse_wchar_t*)xuri.path.ptr + 1)) | ||||||
|  | 		server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_wcsntombsdup ((const qse_wchar_t*)xuri.path.ptr + 1, xuri.path.len - 1, QSE_NULL, httpd->mmgr); | ||||||
|  | 	else | ||||||
| 		server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_wcsntombsdup (xuri.path.ptr, xuri.path.len, QSE_NULL, httpd->mmgr); | 		server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_wcsntombsdup (xuri.path.ptr, xuri.path.len, QSE_NULL, httpd->mmgr); | ||||||
| 	if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM] = qse_wcsntombsdup (xuri.frag.ptr, xuri.frag.len, QSE_NULL, httpd->mmgr); | 	if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM] = qse_wcsntombsdup (xuri.frag.ptr, xuri.frag.len, QSE_NULL, httpd->mmgr); | ||||||
| 	ba.ptr = qse_wcsnatombsdup (tmp, &ba.len, httpd->mmgr); | 	ba.ptr = qse_wcsnatombsdup (tmp, &ba.len, httpd->mmgr); | ||||||
|  | |||||||
| @ -647,10 +647,12 @@ qse_printf (QSE_T(">>>>> Returning failure for client %d\n"), client->handle.i); | |||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| qse_printf (QSE_T("!!!!!FEEDING %d from %d ["), (int)m, (int)client->handle.i); | qse_printf (QSE_T("!!!!!FEEDING %d from %d ["), (int)m, (int)client->handle.i); | ||||||
|  | #if !defined(__OS2__) | ||||||
| { | { | ||||||
| int i; | int i; | ||||||
| for (i = 0; i < m; i++) qse_printf (QSE_T("%hc"), buf[i]); | for (i = 0; i < m; i++) qse_printf (QSE_T("%hc"), buf[i]); | ||||||
| } | } | ||||||
|  | #endif | ||||||
| qse_printf (QSE_T("]\n")); | qse_printf (QSE_T("]\n")); | ||||||
|  |  | ||||||
| 	/* qse_htrd_feed() may call the request callback  | 	/* qse_htrd_feed() may call the request callback  | ||||||
| @ -1134,15 +1136,12 @@ qse_printf (QSE_T("no servers are active....\n")); | |||||||
| 	{ | 	{ | ||||||
| 		int count; | 		int count; | ||||||
|  |  | ||||||
| qse_printf (QSE_T("POLLING %d tmout ..\n"), tmout->sec); |  | ||||||
| 		count = httpd->scb->mux.poll (httpd, httpd->mux, tmout); | 		count = httpd->scb->mux.poll (httpd, httpd->mux, tmout); | ||||||
| qse_printf (QSE_T("POLLING %d return ..\n"), count); |  | ||||||
| 		if (count <= -1) | 		if (count <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			httpd->errnum = QSE_HTTPD_EIOMUX; |  | ||||||
| /* TODO: call user callback for this multiplexer error */ | /* TODO: call user callback for this multiplexer error */ | ||||||
| 			/*if (errno == EINTR) continue;*/ | 			/*if (errno == EINTR) continue;*/ | ||||||
| qse_fprintf (QSE_STDERR, QSE_T("Error: mux returned failure\n")); | qse_fprintf (QSE_STDERR, QSE_T("Error: mux returned failure %d\n"), (int)httpd->errnum); | ||||||
| 			/* break; */ | 			/* break; */ | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user