From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/dktools/dk4sock13.ctr | 305 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 support/dktools/dk4sock13.ctr (limited to 'support/dktools/dk4sock13.ctr') diff --git a/support/dktools/dk4sock13.ctr b/support/dktools/dk4sock13.ctr new file mode 100644 index 0000000000..739ba73c50 --- /dev/null +++ b/support/dktools/dk4sock13.ctr @@ -0,0 +1,305 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + +%% module + +#include "dk4sock.h" + +#include + +#if DK4_HAVE_ERRNO_H +#ifndef ERRNO_H_INCLUDED +#include +#define ERRNO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_UNISTD_H +#ifndef UNISTD_H_INCLUDED +#include +#define UNISTD_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_IO_H +#ifndef IO_H_INCLUDED +#include +#define IO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_STRINGS_H +#ifndef STRINGS_H_INCLUDED +#include +#define STRINGS_H_INCLUDED 1 +#endif +#endif + +#include "dk4mem.h" +#include "dk4stat.h" +#include "dk4stat8.h" +#include "dk4delfile08.h" + + +$!trace-include + + + +int +dk4socket_listen( + dk4_socket_t sock, + int bl, + dk4_er_t *erp +) +{ + int back = DK4_SOCKET_RESULT_FAILED; + if ((INVALID_SOCKET != sock) && (0 < bl)) { + dk4socket_error_reset(); + if (0 == listen(sock, bl)) { + back = DK4_SOCKET_RESULT_SUCCESS; + } else { + dk4socket_error_report(erp, DK4_E_SOCKET_LISTEN); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +dk4_socket_t +dk4socket_accept( + dk4_socket_t sock, + struct sockaddr *pAddr, + size_t *pSzAddr, + dk4_er_t *erp +) +{ + dk4_socket_t back = INVALID_SOCKET; +#if DK4_HAVE_SOCKLEN_T + socklen_t sz; +#else + int sz; +#endif + $? "+ dk4socket_accept %d", (int)sock + if (INVALID_SOCKET != sock) { + if (NULL != pAddr) { $? ". address buffer" + if (NULL != pSzAddr) { $? ". address size pointer" + if (0 < *pSzAddr) { $? ". arguments ok" +#if DK4_HAVE_SOCKLEN_T + sz = (socklen_t)(*pSzAddr); +#else + sz = (int)(*pSzAddr); +#endif + dk4socket_error_reset(); + back = accept(sock, pAddr, &sz); + if (INVALID_SOCKET != back) { + *pSzAddr = (size_t)sz; + } else { + dk4socket_error_report(erp, DK4_E_SOCKET_ACCEPT); + *pSzAddr = 0; + } + } else { $? "! address size 0" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { $? "! no address size pointer" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { $? ". no address buffer" + /* ACCEPT */ + dk4socket_error_reset(); + back = accept(sock, NULL, NULL); + if (INVALID_SOCKET == back) { + dk4socket_error_report(erp, DK4_E_SOCKET_ACCEPT); + } + } + } else { $? "! invalid sock" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4socket_accept %d", back + return back; +} + +#if DK4_HAVE_STRUCT_SOCKADDR_UN + + +/** Change mode and optionally owner and group for a socket. + @param sock Socket file descriptor. + @param filename Socket file name. + @param owner New owner. + @param group New group. + @param mode New file mode. + @param cog Flag: Also change owner and group. + @param erp Error report, may be NULL +*/ +static +int +dk4socket_i_change_owner_group_mode( + dk4_socket_t sock, + const char *filename, + uid_t owner, + gid_t group, + mode_t mode, + int cog, + dk4_er_t *erp +) +{ + int errval; + int back = 1; + $? "+ dk4socket_i_change_owner_group_mode" + if (0 != cog) { + errno = 0; + if (0 != chown(filename, owner, group)) { + errval = errno; + if (0 != fchown(sock, owner, group)) { + back = 0; + dk4error_set_idetails(erp, DK4_E_CHOWN_FAILED, errval); + } + } + } + errno = 0; + if (0 != chmod(filename, mode)) { + errval = errno; + if (0 != fchmod(sock, mode)) { + back = 0; + dk4error_set_idetails(erp, DK4_E_CHMOD_FAILED, errval); + } + } + $? "- dk4socket_i_change_owner_group_mode" + return back; +} + + + +static +dk4_socket_t +dk4socket_i_c8_unix_listener_ogm( + const char *filename, + int backlog, + uid_t owner, + gid_t group, + mode_t mode, + int change, + dk4_er_t *erp +) +{ + struct sockaddr_un soun; + dk4_stat_t stb; + size_t slen; + dk4_socket_t back = INVALID_SOCKET; + int md = 0; + int res; + int ogm1; + int ogm2; + + if ((NULL != filename) && (0 < backlog)) { + if (108 > strlen(filename)) { + /* Attempt to remove existing socket. + */ + res = 1; + if (0 != dk4stat_c8(&stb, filename, NULL)) { + res = 0; + if (0 != dk4stat_is_unix_domain_socket(&stb, NULL)) { + if (0 != dk4delete_file_c8(filename, NULL)) { + res = 1; + } else { + /* ERROR: Failed to remove old socket */ + dk4error_set_simple_error_code(erp, DK4_E_UNLINK_FAILED); + } + } else { + /* ERROR: Not a socket */ + dk4error_set_simple_error_code(erp, DK4_E_NON_SOCKET); + } + } + /* Open and bind new socket. + */ + if (0 != res) { + DK4_MEMRES(&soun, sizeof(soun)); + soun.sun_family = AF_UNIX; + strcpy(soun.sun_path, filename); + slen = dk4socket_unix_length(&soun); + back = dk4socket_open(AF_UNIX, SOCK_STREAM, 0, erp); + if (INVALID_SOCKET != back) { + (void)dk4socket_option_set_reuse(back, 1, NULL); + res = dk4socket_bind( + back, (const struct sockaddr *)(&soun), slen, erp + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { + ogm1 = dk4socket_i_change_owner_group_mode( + back, filename, owner, group, mode, change, erp + ); + res = dk4socket_listen(back, backlog, erp); + if (DK4_SOCKET_RESULT_SUCCESS == res) { + ogm2 = dk4socket_i_change_owner_group_mode( + back, filename, owner, group, mode, change, erp + ); + if ((0 == ogm1) && (0 == ogm2)) { + (void)dk4socket_close(back, NULL); + back = INVALID_SOCKET; + md = 1; + } + } else { + (void)dk4socket_close(back, NULL); + back = INVALID_SOCKET; + md = 1; + } + } else { + (void)dk4socket_close(back, NULL); + back = INVALID_SOCKET; + } + if ((INVALID_SOCKET == back) && (0 != md)) { + (void)dk4delete_file_c8(filename, NULL); + } + } + } else { + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +dk4_socket_t +dk4socket_c8_unix_listener( + const char *filename, + int backlog, + dk4_er_t *erp +) +{ + return ( + dk4socket_i_c8_unix_listener_ogm(filename, backlog, 0, 0, 0660, 0, erp) + ); +} + + + +dk4_socket_t +dk4socket_c8_unix_listener_owner_group_mode( + const char *filename, + int backlog, + uid_t owner, + gid_t group, + mode_t mode, + dk4_er_t *erp +) +{ + return ( + dk4socket_i_c8_unix_listener_ogm( + filename, backlog, owner, group, mode, 1, erp + ) + ); +} + + + + +#endif -- cgit v1.2.3