From 42e75ba731f23355308153116c97a7bfd9bff252 Mon Sep 17 00:00:00 2001 From: Lammert Bies Date: Tue, 27 Dec 2016 18:05:54 +0100 Subject: [PATCH] Replaced strerror with thread safe version --- include/libhttp.h | 1 + src/httplib_accept_new_connection.c | 7 ++++--- src/httplib_check_authorization.c | 3 ++- src/httplib_close_socket_gracefully.c | 3 ++- src/httplib_connect_client.c | 5 +++-- src/httplib_connect_socket.c | 5 +++-- src/httplib_delete_file.c | 3 ++- src/httplib_error_string.c | 6 +++--- src/httplib_fclose_on_exec.c | 4 +++- src/httplib_handle_cgi_request.c | 11 ++++++----- src/httplib_handle_directory_request.c | 3 ++- src/httplib_handle_static_file_request.c | 3 ++- src/httplib_main.h | 2 +- src/httplib_mkcol.c | 15 ++++++++------- src/httplib_open_auth_file.c | 9 ++++++--- src/httplib_put_file.c | 7 ++++--- src/httplib_remove_directory.c | 3 ++- src/httplib_scan_directory.c | 3 ++- src/httplib_send_file_data.c | 3 ++- src/httplib_set_close_on_exec.c | 4 +++- src/httplib_set_gpass_option.c | 3 ++- src/httplib_set_ports_option.c | 9 +++++---- src/httplib_set_uid_option.c | 7 ++++--- src/httplib_spawn_process.c | 15 ++++++++------- src/httplib_ssi.c | 9 ++++++--- src/main.c | 12 ++++++++---- 26 files changed, 94 insertions(+), 61 deletions(-) diff --git a/include/libhttp.h b/include/libhttp.h index 7ac9ec1d..e582ff9e 100644 --- a/include/libhttp.h +++ b/include/libhttp.h @@ -940,6 +940,7 @@ LIBHTTP_API int httplib_base64_encode( const unsigned char *src, int src_len, LIBHTTP_API unsigned httplib_check_feature( unsigned feature ); LIBHTTP_API int httplib_closedir( DIR *dir ); LIBHTTP_API void httplib_cry( const struct httplib_context *ctx, const struct httplib_connection *conn, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4); +LIBHTTP_API char * httplib_error_string( int error_code, char *buf, size_t buf_len ); LIBHTTP_API const char * httplib_get_builtin_mime_type( const char *file_name ); LIBHTTP_API uint64_t httplib_get_random( void ); LIBHTTP_API void * httplib_get_user_connection_data( const struct httplib_connection *conn ); diff --git a/src/httplib_accept_new_connection.c b/src/httplib_accept_new_connection.c index a90bddba..bd042b35 100644 --- a/src/httplib_accept_new_connection.c +++ b/src/httplib_accept_new_connection.c @@ -39,6 +39,7 @@ void XX_httplib_accept_new_connection( const struct socket *listener, struct htt struct socket so; char src_addr[IP_ADDR_STR_LEN]; + char error_string[ERROR_STRING_LEN]; socklen_t len; int on; int timeout; @@ -72,7 +73,7 @@ void XX_httplib_accept_new_connection( const struct socket *listener, struct htt if ( getsockname( so.sock, &so.lsa.sa, &len ) != 0 ) { - httplib_cry( ctx, NULL, "%s: getsockname() failed: %s", __func__, strerror(ERRNO) ); + httplib_cry( ctx, NULL, "%s: getsockname() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } /* @@ -86,7 +87,7 @@ void XX_httplib_accept_new_connection( const struct socket *listener, struct htt if ( setsockopt( so.sock, SOL_SOCKET, SO_KEEPALIVE, (SOCK_OPT_TYPE)&on, sizeof(on) ) != 0 ) { - httplib_cry( ctx, NULL, "%s: setsockopt(SOL_SOCKET SO_KEEPALIVE) failed: %s", __func__, strerror(ERRNO) ); + httplib_cry( ctx, NULL, "%s: setsockopt(SOL_SOCKET SO_KEEPALIVE) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } /* @@ -102,7 +103,7 @@ void XX_httplib_accept_new_connection( const struct socket *listener, struct htt if ( XX_httplib_set_tcp_nodelay( so.sock, 1 ) != 0 ) { - httplib_cry( ctx, NULL, "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s", __func__, strerror(ERRNO) ); + httplib_cry( ctx, NULL, "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } diff --git a/src/httplib_check_authorization.c b/src/httplib_check_authorization.c index 38f9b1a7..d7e7c168 100644 --- a/src/httplib_check_authorization.c +++ b/src/httplib_check_authorization.c @@ -32,6 +32,7 @@ bool XX_httplib_check_authorization( struct httplib_connection *conn, const char *path ) { char fname[PATH_MAX]; + char error_string[ERROR_STRING_LEN]; struct vec uri_vec; struct vec filename_vec; const char *list; @@ -53,7 +54,7 @@ bool XX_httplib_check_authorization( struct httplib_connection *conn, const char if ( truncated || ! XX_httplib_fopen( conn, fname, "r", &file ) ) { - httplib_cry( conn->ctx, conn, "%s: cannot open %s: %s", __func__, fname, strerror(errno) ); + httplib_cry( conn->ctx, conn, "%s: cannot open %s: %s", __func__, fname, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } break; } diff --git a/src/httplib_close_socket_gracefully.c b/src/httplib_close_socket_gracefully.c index d0a5c7f2..247653a1 100644 --- a/src/httplib_close_socket_gracefully.c +++ b/src/httplib_close_socket_gracefully.c @@ -40,6 +40,7 @@ void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) { char buf[MG_BUF_LEN]; int n; #endif + char error_string[ERROR_STRING_LEN]; struct linger linger; int error_code; socklen_t opt_len; @@ -66,7 +67,7 @@ void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) { else { if ( setsockopt( conn->client.sock, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger) ) != 0 ) { - httplib_cry( conn->ctx, conn, "%s: setsockopt(SOL_SOCKET SO_LINGER) failed: %s", __func__, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: setsockopt(SOL_SOCKET SO_LINGER) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } diff --git a/src/httplib_connect_client.c b/src/httplib_connect_client.c index f1404b2d..13f1cde6 100644 --- a/src/httplib_connect_client.c +++ b/src/httplib_connect_client.c @@ -82,12 +82,13 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http union usa sa; socklen_t len; struct sockaddr *psa; + char error_string[ERROR_STRING_LEN]; if ( ! XX_httplib_connect_socket( &fake_ctx, client_options->host, client_options->port, use_ssl, ebuf, ebuf_len, &sock, &sa ) ) return NULL; if ( (conn = httplib_calloc( 1, sizeof(*conn) + MAX_REQUEST_SIZE )) == NULL ) { - XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "calloc(): %s", strerror(ERRNO) ); + XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "calloc(): %s", httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); closesocket( sock ); } #ifndef NO_SSL @@ -112,7 +113,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http conn->client.sock = sock; conn->client.lsa = sa; - if ( getsockname( sock, psa, &len ) != 0 ) httplib_cry( &fake_ctx, conn, "%s: getsockname() failed: %s", __func__, strerror(ERRNO) ); + if ( getsockname( sock, psa, &len ) != 0 ) httplib_cry( &fake_ctx, conn, "%s: getsockname() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); conn->client.has_ssl = (use_ssl) ? true : false; httplib_pthread_mutex_init( &conn->mutex, &XX_httplib_pthread_mutex_attr ); diff --git a/src/httplib_connect_socket.c b/src/httplib_connect_socket.c index 6c9b6ca3..96251802 100644 --- a/src/httplib_connect_socket.c +++ b/src/httplib_connect_socket.c @@ -41,6 +41,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, SOCKET *sock, union usa *sa ) { int ip_ver; + char error_string[ERROR_STRING_LEN]; ip_ver = 0; *sock = INVALID_SOCKET; @@ -117,7 +118,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in if ( *sock == INVALID_SOCKET ) { - XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "socket(): %s", strerror(ERRNO) ); + XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "socket(): %s", httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return 0; } @@ -130,7 +131,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in * Not connected */ - XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "connect(%s:%d): %s", host, port, strerror(ERRNO) ); + XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "connect(%s:%d): %s", host, port, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); closesocket( *sock ); *sock = INVALID_SOCKET; diff --git a/src/httplib_delete_file.c b/src/httplib_delete_file.c index fa67fbb3..6234b119 100644 --- a/src/httplib_delete_file.c +++ b/src/httplib_delete_file.c @@ -37,6 +37,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) { struct de de; + char error_string[ERROR_STRING_LEN]; if ( conn == NULL || conn->ctx == NULL ) return; if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) { @@ -108,6 +109,6 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) */ if ( httplib_remove( path ) == 0 ) XX_httplib_send_http_error( conn, 204, "%s", "" ); - else XX_httplib_send_http_error( conn, 423, "Error: Cannot delete file\nremove(%s): %s", path, strerror(ERRNO) ); + else XX_httplib_send_http_error( conn, 423, "Error: Cannot delete file\nremove(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } /* XX_httplib_delete_file */ diff --git a/src/httplib_error_string.c b/src/httplib_error_string.c index 142de734..b09df4d2 100644 --- a/src/httplib_error_string.c +++ b/src/httplib_error_string.c @@ -30,7 +30,7 @@ #endif /* - * char *XX_httplib_error_string( int error_code, char *buf, size_t buf_len ); + * char *httplib_error_string( int error_code, char *buf, size_t buf_len ); * * The function XX_httplib_error_string() returns a string associated with an * error code by storing it in a caller provided buffer. The function returns a @@ -42,7 +42,7 @@ * The implementation of the function is thread safe. */ -char *XX_httplib_error_string( int error_code, char *buf, size_t buf_len ) { +LIBHTTP_API char *httplib_error_string( int error_code, char *buf, size_t buf_len ) { if ( buf == NULL || buf_len < 1 ) return NULL; @@ -172,4 +172,4 @@ char *XX_httplib_error_string( int error_code, char *buf, size_t buf_len ) { #endif /* _WIN32 */ -} /* XX_httplib_error_string */ +} /* httplib_error_string */ diff --git a/src/httplib_fclose_on_exec.c b/src/httplib_fclose_on_exec.c index c0401c71..5bafb6f3 100644 --- a/src/httplib_fclose_on_exec.c +++ b/src/httplib_fclose_on_exec.c @@ -29,6 +29,8 @@ void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection *conn ) { + char error_string[ERROR_STRING_LEN]; + if ( filep == NULL || filep->fp == NULL ) return; #ifdef _WIN32 @@ -36,7 +38,7 @@ void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection *c #else if ( fcntl( fileno( filep->fp ), F_SETFD, FD_CLOEXEC) != 0 ) { - if ( conn != NULL && conn->ctx != NULL ) httplib_cry( conn->ctx, conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO) ); + if ( conn != NULL && conn->ctx != NULL ) httplib_cry( conn->ctx, conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } #endif diff --git a/src/httplib_handle_cgi_request.c b/src/httplib_handle_cgi_request.c index 6490f2e5..2abf6d1e 100644 --- a/src/httplib_handle_cgi_request.c +++ b/src/httplib_handle_cgi_request.c @@ -53,6 +53,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char const char *connection_state; char *pbuf; char dir[PATH_MAX]; + char error_string[ERROR_STRING_LEN]; char *ptr; const char *cptr; struct httplib_request_info ri; @@ -104,7 +105,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0 ) { - status = strerror( ERRNO ); + status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); httplib_cry( conn->ctx, conn, "Error: CGI program \"%s\": Can not create CGI pipes: %s", prog, status ); XX_httplib_send_http_error( conn, 500, "Error: Cannot create CGI pipe: %s", status ); @@ -115,7 +116,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( pid == (pid_t)-1 ) { - status = strerror(ERRNO); + status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); httplib_cry( conn->ctx, conn, "Error: CGI program \"%s\": Can not spawn CGI process: %s", prog, status ); XX_httplib_send_http_error( conn, 500, "Error: Cannot spawn CGI process [%s]: %s", prog, status ); @@ -150,7 +151,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( (in = fdopen( fdin[1], "wb" )) == NULL ) { - status = strerror(ERRNO); + status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); httplib_cry( conn->ctx, conn, "Error: CGI program \"%s\": Can not open stdin: %s", prog, status ); XX_httplib_send_http_error( conn, 500, "Error: CGI can not open fdin\nfopen: %s", status ); @@ -159,7 +160,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( (out = fdopen( fdout[0], "rb" )) == NULL ) { - status = strerror(ERRNO); + status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); httplib_cry( conn->ctx, conn, "Error: CGI program \"%s\": Can not open stdout: %s", prog, status ); XX_httplib_send_http_error( conn, 500, "Error: CGI can not open fdout\nfopen: %s", status ); @@ -168,7 +169,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( (err = fdopen( fderr[0], "rb" )) == NULL ) { - status = strerror(ERRNO); + status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); httplib_cry( conn->ctx, conn, "Error: CGI program \"%s\": Can not open stderr: %s", prog, status ); XX_httplib_send_http_error( conn, 500, "Error: CGI can not open fdout\nfopen: %s", status ); diff --git a/src/httplib_handle_directory_request.c b/src/httplib_handle_directory_request.c index f6efebe4..e2084191 100644 --- a/src/httplib_handle_directory_request.c +++ b/src/httplib_handle_directory_request.c @@ -34,6 +34,7 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const int sort_direction; struct dir_scan_data data = { NULL, 0, 128 }; char date[64]; + char error_string[ERROR_STRING_LEN]; time_t curtime; if ( conn == NULL || conn->ctx == NULL ) return; @@ -41,7 +42,7 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const if ( ! XX_httplib_scan_directory( conn, dir, & data, XX_httplib_dir_scan_callback ) ) { - XX_httplib_send_http_error( conn, 500, "Error: Cannot open directory\nopendir(%s): %s", dir, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 500, "Error: Cannot open directory\nopendir(%s): %s", dir, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } diff --git a/src/httplib_handle_static_file_request.c b/src/httplib_handle_static_file_request.c index c847f5e4..f40dfb1c 100644 --- a/src/httplib_handle_static_file_request.c +++ b/src/httplib_handle_static_file_request.c @@ -52,6 +52,7 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con int n; bool truncated; char gz_path[PATH_MAX]; + char error_string[ERROR_STRING_LEN]; const char *encoding; const char *cors1; const char *cors2; @@ -98,7 +99,7 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con if ( ! XX_httplib_fopen( conn, path, "rb", filep ) ) { - XX_httplib_send_http_error( conn, 500, "Error: Cannot open file\nfopen(%s): %s", path, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 500, "Error: Cannot open file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } diff --git a/src/httplib_main.h b/src/httplib_main.h index f98afa87..65f1fc4b 100644 --- a/src/httplib_main.h +++ b/src/httplib_main.h @@ -511,6 +511,7 @@ extern CRITICAL_SECTION global_log_file_lock; #define CGI_ENVIRONMENT_SIZE (4096) #define MAX_CGI_ENVIR_VARS (256) #define MG_BUF_LEN (8192) +#define ERROR_STRING_LEN (256) /* * TODO: LJB: Move to test functions @@ -805,7 +806,6 @@ int XX_httplib_consume_socket( struct httplib_context *ctx, struct socket *sp, void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ); void XX_httplib_dir_scan_callback( struct de *de, void *data ); void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ); -char * XX_httplib_error_string( int error_code, char *buf, size_t buf_len ); int XX_httplib_fclose( struct file *filep ); void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection *conn ); const char * XX_httplib_fgets( char *buf, size_t size, struct file *filep, char **p ); diff --git a/src/httplib_mkcol.c b/src/httplib_mkcol.c index f2cacc77..63dcefe7 100644 --- a/src/httplib_mkcol.c +++ b/src/httplib_mkcol.c @@ -43,6 +43,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { struct de de; char date[64]; time_t curtime; + char error_string[ERROR_STRING_LEN]; if ( conn == NULL || conn->ctx == NULL ) return; if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; @@ -57,7 +58,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { if ( ! XX_httplib_stat( conn, path, & de.file ) ) { - httplib_cry( conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } if ( de.file.last_modified ) { @@ -66,7 +67,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { * TODO (high): This check does not seem to make any sense ! */ - XX_httplib_send_http_error( conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 405, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -74,7 +75,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { if ( body_len > 0 ) { - XX_httplib_send_http_error( conn, 415, "Error: mkcol(%s): %s", path, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 415, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -91,10 +92,10 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { else if ( rc == -1 ) { - if ( errno == EEXIST ) XX_httplib_send_http_error( conn, 405, "Error: mkcol(%s): %s", path, strerror( ERRNO ) ); - else if ( errno == EACCES ) XX_httplib_send_http_error( conn, 403, "Error: mkcol(%s): %s", path, strerror( ERRNO ) ); - else if ( errno == ENOENT ) XX_httplib_send_http_error( conn, 409, "Error: mkcol(%s): %s", path, strerror( ERRNO ) ); - else XX_httplib_send_http_error( conn, 500, "fopen(%s): %s", path, strerror( ERRNO ) ); + if ( errno == EEXIST ) XX_httplib_send_http_error( conn, 405, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( errno == EACCES ) XX_httplib_send_http_error( conn, 403, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( errno == ENOENT ) XX_httplib_send_http_error( conn, 409, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else XX_httplib_send_http_error( conn, 500, "fopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } /* XX_httplib_mkcol */ diff --git a/src/httplib_open_auth_file.c b/src/httplib_open_auth_file.c index 27f673c4..8289faff 100644 --- a/src/httplib_open_auth_file.c +++ b/src/httplib_open_auth_file.c @@ -33,6 +33,9 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *path, struct file *filep ) { char name[PATH_MAX]; +#ifdef DEBUG + char error_string[ERROR_STRING_LEN]; +#endif const char *p; const char *e; const char *gpass; @@ -51,7 +54,7 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat if ( ! XX_httplib_fopen( conn, gpass, "r", filep ) ) { #ifdef DEBUG - httplib_cry( conn, "fopen(%s): %s", gpass, strerror(ERRNO) ); + httplib_cry( conn, "fopen(%s): %s", gpass, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); #endif } /* @@ -68,7 +71,7 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat if ( truncated || ! XX_httplib_fopen( conn, name, "r", filep ) ) { #ifdef DEBUG - httplib_cry( conn, "fopen(%s): %s", name, strerror(ERRNO) ); + httplib_cry( conn, "fopen(%s): %s", name, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); #endif } } @@ -86,7 +89,7 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat if ( truncated || ! XX_httplib_fopen( conn, name, "r", filep ) ) { #ifdef DEBUG - httplib_cry( conn, "fopen(%s): %s", name, strerror(ERRNO) ); + httplib_cry( conn, "fopen(%s): %s", name, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); #endif } } diff --git a/src/httplib_put_file.c b/src/httplib_put_file.c index 8cdc5a8a..bdfd792f 100644 --- a/src/httplib_put_file.c +++ b/src/httplib_put_file.c @@ -43,6 +43,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { int64_t r2; int rc; char date[64]; + char error_string[ERROR_STRING_LEN]; time_t curtime; if ( conn == NULL || conn->ctx == NULL ) return; @@ -140,7 +141,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { * XX_httplib_put_dir returns -1 if the path is too long */ - XX_httplib_send_http_error( conn, 414, "Error: Path too long\nput_dir(%s): %s", path, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 414, "Error: Path too long\nput_dir(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -150,7 +151,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { * XX_httplib_put_dir returns -2 if the directory can not be created */ - XX_httplib_send_http_error( conn, 500, "Error: Can not create directory\nput_dir(%s): %s", path, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 500, "Error: Can not create directory\nput_dir(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -161,7 +162,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { if ( ! XX_httplib_fopen( conn, path, "wb+", &file) || file.fp == NULL ) { XX_httplib_fclose( & file ); - XX_httplib_send_http_error( conn, 500, "Error: Can not create file\nfopen(%s): %s", path, strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 500, "Error: Can not create file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } diff --git a/src/httplib_remove_directory.c b/src/httplib_remove_directory.c index 3e2af178..4f7c5e11 100644 --- a/src/httplib_remove_directory.c +++ b/src/httplib_remove_directory.c @@ -38,6 +38,7 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *dir ) { char path[PATH_MAX]; + char error_string[ERROR_STRING_LEN]; struct dirent *dp; DIR *dirp; struct de de; @@ -84,7 +85,7 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *di if ( ! XX_httplib_stat( conn, path, & de.file ) ) { - httplib_cry( conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); ok = 0; } if ( de.file.membuf == NULL ) { diff --git a/src/httplib_scan_directory.c b/src/httplib_scan_directory.c index 695de5e9..ccec57b0 100644 --- a/src/httplib_scan_directory.c +++ b/src/httplib_scan_directory.c @@ -31,6 +31,7 @@ int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, void *data, void (*cb)(struct de *, void *) ) { char path[PATH_MAX]; + char error_string[ERROR_STRING_LEN]; struct dirent *dp; DIR *dirp; struct de de; @@ -65,7 +66,7 @@ int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, if ( ! XX_httplib_stat( conn, path, &de.file ) ) { - httplib_cry( conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } de.file_name = dp->d_name; diff --git a/src/httplib_send_file_data.c b/src/httplib_send_file_data.c index 59d2e0c8..faf3bf5a 100644 --- a/src/httplib_send_file_data.c +++ b/src/httplib_send_file_data.c @@ -37,6 +37,7 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *filep, int64_t offset, int64_t len ) { char buf[MG_BUF_LEN]; + char error_string[ERROR_STRING_LEN]; int to_read; int num_read; int num_written; @@ -142,7 +143,7 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi #endif if ( offset > 0 && fseeko( filep->fp, offset, SEEK_SET ) != 0 ) { - httplib_cry( conn->ctx, conn, "%s: fseeko() failed: %s", __func__, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: fseeko() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); XX_httplib_send_http_error( conn, 500, "%s", "Error: Unable to access file at requested position." ); } diff --git a/src/httplib_set_close_on_exec.c b/src/httplib_set_close_on_exec.c index 9e491fbb..e750c2a0 100644 --- a/src/httplib_set_close_on_exec.c +++ b/src/httplib_set_close_on_exec.c @@ -41,9 +41,11 @@ void XX_httplib_set_close_on_exec( SOCKET fd, const struct httplib_context *ctx #else /* _WIN32 */ + char error_string[ERROR_STRING_LEN]; + if ( fcntl( fd, F_SETFD, FD_CLOEXEC ) != 0 ) { - if ( ctx != NULL ) httplib_cry( ctx, NULL, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO) ); + if ( ctx != NULL ) httplib_cry( ctx, NULL, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } #endif /* _WIN32 */ diff --git a/src/httplib_set_gpass_option.c b/src/httplib_set_gpass_option.c index 4775925d..79eace72 100644 --- a/src/httplib_set_gpass_option.c +++ b/src/httplib_set_gpass_option.c @@ -38,6 +38,7 @@ int XX_httplib_set_gpass_option( struct httplib_context *ctx ) { struct file file = STRUCT_FILE_INITIALIZER; const char *path; + char error_string[ERROR_STRING_LEN]; if ( ctx == NULL ) return 0; @@ -45,7 +46,7 @@ int XX_httplib_set_gpass_option( struct httplib_context *ctx ) { if ( path != NULL && ! XX_httplib_stat( NULL, path, &file ) ) { - httplib_cry( ctx, NULL, "Cannot open %s: %s", path, strerror(ERRNO) ); + httplib_cry( ctx, NULL, "Cannot open %s: %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return 0; } return 1; diff --git a/src/httplib_set_ports_option.c b/src/httplib_set_ports_option.c index 79c53561..643cd9e4 100644 --- a/src/httplib_set_ports_option.c +++ b/src/httplib_set_ports_option.c @@ -41,6 +41,7 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip int XX_httplib_set_ports_option( struct httplib_context *ctx ) { const char *list; + char error_string[ERROR_STRING_LEN]; int on; int off; struct vec vec; @@ -149,7 +150,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { if ( bind( so.sock, &so.lsa.sa, len ) != 0 ) { - httplib_cry( ctx, NULL, "cannot bind to %.*s: %d (%s)", (int)vec.len, vec.ptr, (int)ERRNO, strerror(errno) ); + httplib_cry( ctx, NULL, "cannot bind to %.*s: %d (%s)", (int)vec.len, vec.ptr, (int)ERRNO, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); closesocket( so.sock ); so.sock = INVALID_SOCKET; continue; @@ -162,7 +163,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { if ( bind( so.sock, &so.lsa.sa, len ) != 0 ) { - httplib_cry( ctx, NULL, "cannot bind to IPv6 %.*s: %d (%s)", (int)vec.len, vec.ptr, (int)ERRNO, strerror(errno) ); + httplib_cry( ctx, NULL, "cannot bind to IPv6 %.*s: %d (%s)", (int)vec.len, vec.ptr, (int)ERRNO, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); closesocket( so.sock ); so.sock = INVALID_SOCKET; continue; @@ -176,7 +177,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { if ( listen( so.sock, SOMAXCONN ) != 0 ) { - httplib_cry( ctx, NULL, "cannot listen to %.*s: %d (%s)", (int)vec.len, vec.ptr, (int)ERRNO, strerror(errno) ); + httplib_cry( ctx, NULL, "cannot listen to %.*s: %d (%s)", (int)vec.len, vec.ptr, (int)ERRNO, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); closesocket( so.sock ); so.sock = INVALID_SOCKET; continue; @@ -185,7 +186,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { if ( getsockname( so.sock, &(usa.sa), &len ) != 0 || usa.sa.sa_family != so.lsa.sa.sa_family ) { int err = (int)ERRNO; - httplib_cry( ctx, NULL, "call to getsockname failed %.*s: %d (%s)", (int)vec.len, vec.ptr, err, strerror(errno) ); + httplib_cry( ctx, NULL, "call to getsockname failed %.*s: %d (%s)", (int)vec.len, vec.ptr, err, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); closesocket( so.sock ); so.sock = INVALID_SOCKET; continue; diff --git a/src/httplib_set_uid_option.c b/src/httplib_set_uid_option.c index 2636300b..2b5135ad 100644 --- a/src/httplib_set_uid_option.c +++ b/src/httplib_set_uid_option.c @@ -48,6 +48,7 @@ bool XX_httplib_set_uid_option( struct httplib_context *ctx ) { struct passwd *pw; const char *uid; + char error_string[ERROR_STRING_LEN]; if ( ctx == NULL ) return false; @@ -56,9 +57,9 @@ bool XX_httplib_set_uid_option( struct httplib_context *ctx ) { if ( uid == NULL ) return true; if ( (pw = getpwnam(uid)) == NULL ) httplib_cry( ctx, NULL, "%s: unknown user [%s]", __func__, uid ); - else if ( setgid(pw->pw_gid) == -1 ) httplib_cry( ctx, NULL, "%s: setgid(%s): %s", __func__, uid, strerror(errno) ); - else if ( setgroups(0, NULL) ) httplib_cry( ctx, NULL, "%s: setgroups(): %s", __func__, strerror(errno) ); - else if ( setuid(pw->pw_uid) == -1 ) httplib_cry( ctx, NULL, "%s: setuid(%s): %s", __func__, uid, strerror(errno) ); + else if ( setgid(pw->pw_gid) == -1 ) httplib_cry( ctx, NULL, "%s: setgid(%s): %s", __func__, uid, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( setgroups(0, NULL) ) httplib_cry( ctx, NULL, "%s: setgroups(): %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( setuid(pw->pw_uid) == -1 ) httplib_cry( ctx, NULL, "%s: setuid(%s): %s", __func__, uid, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); else return true; return false; diff --git a/src/httplib_spawn_process.c b/src/httplib_spawn_process.c index c6d7ca84..62997891 100644 --- a/src/httplib_spawn_process.c +++ b/src/httplib_spawn_process.c @@ -159,6 +159,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro pid_t pid; const char *interp; + char error_string[ERROR_STRING_LEN]; UNUSED_PARAMETER(envblk); @@ -170,7 +171,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro * Parent */ - XX_httplib_send_http_error( conn, 500, "Error: Creating CGI process\nfork(): %s", strerror(ERRNO) ); + XX_httplib_send_http_error( conn, 500, "Error: Creating CGI process\nfork(): %s", httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else if ( pid == 0 ) { @@ -179,10 +180,10 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro * Child */ - if ( chdir( dir ) != 0 ) httplib_cry( conn->ctx, conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO) ); - else if ( dup2( fdin[0], 0 ) == -1 ) httplib_cry( conn->ctx, conn, "%s: dup2(%d, 0): %s", __func__, fdin[0], strerror(ERRNO) ); - else if ( dup2( fdout[1], 1 ) == -1 ) httplib_cry( conn->ctx, conn, "%s: dup2(%d, 1): %s", __func__, fdout[1], strerror(ERRNO) ); - else if ( dup2( fderr[1], 2 ) == -1 ) httplib_cry( conn->ctx, conn, "%s: dup2(%d, 2): %s", __func__, fderr[1], strerror(ERRNO) ); + if ( chdir( dir ) != 0 ) httplib_cry( conn->ctx, conn, "%s: chdir(%s): %s", __func__, dir, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( dup2( fdin[0], 0 ) == -1 ) httplib_cry( conn->ctx, conn, "%s: dup2(%d, 0): %s", __func__, fdin[0], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( dup2( fdout[1], 1 ) == -1 ) httplib_cry( conn->ctx, conn, "%s: dup2(%d, 1): %s", __func__, fdout[1], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( dup2( fderr[1], 2 ) == -1 ) httplib_cry( conn->ctx, conn, "%s: dup2(%d, 2): %s", __func__, fderr[1], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); else { /* * Keep stderr and stdout in two different pipes. @@ -217,12 +218,12 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro if ( interp == NULL ) { execle( prog, prog, NULL, envp ); - httplib_cry( conn->ctx, conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: execle(%s): %s", __func__, prog, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else { execle( interp, interp, prog, NULL, envp ); - httplib_cry( conn->ctx, conn, "%s: execle(%s %s): %s", __func__, interp, prog, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "%s: execle(%s %s): %s", __func__, interp, prog, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } diff --git a/src/httplib_ssi.c b/src/httplib_ssi.c index 5a42c936..83fd662b 100644 --- a/src/httplib_ssi.c +++ b/src/httplib_ssi.c @@ -36,6 +36,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch char file_name[MG_BUF_LEN]; char path[512]; + char error_string[ERROR_STRING_LEN]; const char *doc_root; const char *ssi_ext; char *p; @@ -109,7 +110,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch if ( ! XX_httplib_fopen( conn, path, "rb", &file ) ) { - httplib_cry( conn->ctx, conn, "Cannot open SSI #include: [%s]: fopen(%s): %s", tag, path, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "Cannot open SSI #include: [%s]: fopen(%s): %s", tag, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -129,6 +130,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch static void do_ssi_exec( struct httplib_connection *conn, char *tag ) { char cmd[1024] = ""; + char error_string[ERROR_STRING_LEN]; struct file file = STRUCT_FILE_INITIALIZER; if ( sscanf(tag, " \"%1023[^\"]\"", cmd) != 1 ) { @@ -140,7 +142,7 @@ static void do_ssi_exec( struct httplib_connection *conn, char *tag ) { cmd[1023] = 0; if ( (file.fp = popen( cmd, "r" ) ) == NULL ) { - httplib_cry( conn->ctx, conn, "Cannot SSI #exec: [%s]: %s", cmd, strerror(ERRNO) ); + httplib_cry( conn->ctx, conn, "Cannot SSI #exec: [%s]: %s", cmd, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else { @@ -270,6 +272,7 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const char *path, struct file *filep ) { char date[64]; + char error_string[ERROR_STRING_LEN]; time_t curtime; const char *cors1; const char *cors2; @@ -303,7 +306,7 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const * but can not be opened by the server. */ - XX_httplib_send_http_error(conn, 500, "Error: Cannot read file\nfopen(%s): %s", path, strerror(ERRNO)); + XX_httplib_send_http_error(conn, 500, "Error: Cannot read file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else { diff --git a/src/main.c b/src/main.c index 4090a175..f58cbdfc 100644 --- a/src/main.c +++ b/src/main.c @@ -125,6 +125,10 @@ static int guard = 0; /* test if any dialog is already open */ #define PATH_MAX (1024) #endif +#ifndef ERROR_STRING_LEN +#define ERROR_STRING_LEN (256) +#endif + #define MAX_OPTIONS (50) #define MAX_CONF_FILE_LINE_SIZE (8 * 1024) @@ -503,6 +507,7 @@ static int read_config_file(const char *config_file, char **options) { static void process_command_line_arguments(int argc, char *argv[], char **options) { char *p; + char error_string[ERROR_STRING_LEN]; size_t i, cmd_line_opts_start = 1; #ifdef CONFIG_FILE2 FILE *fp = NULL; @@ -547,9 +552,7 @@ static void process_command_line_arguments(int argc, char *argv[], char **option if (cmd_line_opts_start == 2) { /* If config file was set in command line and open failed, die. */ /* Errno will still hold the error from fopen. */ - die("Cannot open config file %s: %s", - g_config_file_name, - strerror(errno)); + die( "Cannot open config file %s: %s", g_config_file_name, httplib_error_string( errno, error_string, ERROR_STRING_LEN ) ); } /* Otherwise: LibHTTP can work without a config file */ } @@ -639,6 +642,7 @@ static int is_path_absolute(const char *path) { static void verify_existence(char **options, const char *option_name, int must_be_dir) { struct stat st; + char error_string[ERROR_STRING_LEN]; const char *path = get_option(options, option_name); #ifdef _WIN32 @@ -662,7 +666,7 @@ static void verify_existence(char **options, const char *option_name, int must_b "absolute, or it is relative to libhttp executable.", option_name, path, - strerror(errno)); + httplib_error_string( errno, error_string, ERROR_STRING_LEN ) ); } }