├── AUTHORS ├── COPYING.LIB ├── ChangeLog ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── README.md ├── TODO ├── aux-build ├── compile ├── config.guess ├── config.rpath ├── config.sub ├── depcomp ├── install-sh ├── ltmain.sh ├── missing ├── mkinstalldirs ├── test-driver ├── texinfo.tex └── ylwrap ├── config.h.in ├── configure.ac ├── doc ├── LGPL.texi ├── Makefile.am ├── cbase.texi └── texinfo.tex ├── docs ├── _config.yml ├── cbase_manual.html ├── cbase_manual.pdf ├── dist │ └── cbase-1.4.tar.gz └── index.md ├── lib ├── Makefile.am ├── bitstring.c ├── btree.c ├── byteord.c ├── cbase │ ├── cbase.h │ ├── cerrno.h │ ├── data.h │ ├── defs.h │ ├── except.h │ ├── http.h │ ├── ipc.h │ ├── net.h │ ├── sched.h │ ├── system.h │ ├── util.h │ └── version.h ├── darray.c ├── debug.c ├── dlobject.c ├── dstring.c ├── error.c ├── except.c ├── exec.c ├── file.c ├── filedesc.c ├── getXXbyYY_r.c ├── getXXbyYY_r.h ├── hashtab.c ├── hex.c ├── httpsrv.c ├── io.c ├── libcbase.pc.in ├── libcbase_mt.pc.in ├── linklist.c ├── log.c ├── memfile.c ├── memory.c ├── mempool.c ├── netcommon.h ├── netinfo.c ├── pty.c ├── random.c ├── sched.c ├── sem.c ├── shmem.c ├── signals.c ├── sockctl.c ├── sockio.c ├── strbuf.c ├── strings.c ├── system.c ├── template.h ├── time.c ├── timer.c ├── tty.c ├── vector.c └── version.c └── m4 ├── libtool.m4 ├── ltoptions.m4 ├── ltsugar.m4 ├── ltversion.m4 └── lt~obsolete.m4 /AUTHORS: -------------------------------------------------------------------------------- 1 | Original Authors 2 | ---------------- 3 | 4 | Mark Lindner 5 | 6 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | SUBDIRS = lib doc 4 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperrealm/cbase/b12cf720ed43c75e26302d7959ba6608f0603c53/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | This package may not compile with older versions of gcc. Version 3.3 3 | or later is highly recommended. This is especially true on OS X. 4 | 5 | To generate a nice printable manual, issue the command `make pdf'. 6 | 7 | This package is no longer being actively developed, as I've switched 8 | to C++ for all non-trivial systems software development. All 9 | forseeable future releases of cbase will be for bugfixes only. If you 10 | are interested in taking ownership of this package and developing it 11 | further, please contact me by leaving me feedback at 12 | http://www.hyperrealm.com/ 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cbase 2 | C Foundation Library 3 | 4 | Visit the [cbase project page](https://hyperrealm.github.io/cbase/) 5 | for distribution tarballs and other info. 6 | 7 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - test btree cleanup functions 2 | -------------------------------------------------------------------------------- /aux-build/missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common wrapper for a few potentially missing GNU and other programs. 3 | 4 | scriptversion=2024-06-07.14; # UTC 5 | 6 | # shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells 7 | 8 | # Copyright (C) 1996-2024 Free Software Foundation, Inc. 9 | # Originally written by Fran,cois Pinard , 1996. 10 | 11 | # This program is free software; you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation; either version 2, or (at your option) 14 | # any later version. 15 | 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | 21 | # You should have received a copy of the GNU General Public License 22 | # along with this program. If not, see . 23 | 24 | # As a special exception to the GNU General Public License, if you 25 | # distribute this file as part of a program that contains a 26 | # configuration script generated by Autoconf, you may include it under 27 | # the same distribution terms that you use for the rest of that program. 28 | 29 | if test $# -eq 0; then 30 | echo 1>&2 "Try '$0 --help' for more information" 31 | exit 1 32 | fi 33 | 34 | case $1 in 35 | 36 | --is-lightweight) 37 | # Used by our autoconf macros to check whether the available missing 38 | # script is modern enough. 39 | exit 0 40 | ;; 41 | 42 | --run) 43 | # Back-compat with the calling convention used by older automake. 44 | shift 45 | ;; 46 | 47 | -h|--h|--he|--hel|--help) 48 | echo "\ 49 | $0 [OPTION]... PROGRAM [ARGUMENT]... 50 | 51 | Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due 52 | to PROGRAM being missing or too old. 53 | 54 | Options: 55 | -h, --help display this help and exit 56 | -v, --version output version information and exit 57 | 58 | Supported PROGRAM values: 59 | aclocal autoconf autogen autoheader autom4te automake autoreconf 60 | bison flex help2man lex makeinfo perl yacc 61 | 62 | Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 63 | 'g' are ignored when checking the name. 64 | 65 | Report bugs to . 66 | GNU Automake home page: . 67 | General help using GNU software: ." 68 | exit $? 69 | ;; 70 | 71 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 72 | echo "missing (GNU Automake) $scriptversion" 73 | exit $? 74 | ;; 75 | 76 | -*) 77 | echo 1>&2 "$0: unknown '$1' option" 78 | echo 1>&2 "Try '$0 --help' for more information" 79 | exit 1 80 | ;; 81 | 82 | esac 83 | 84 | # Run the given program, remember its exit status. 85 | "$@"; st=$? 86 | 87 | # If it succeeded, we are done. 88 | test $st -eq 0 && exit 0 89 | 90 | # Also exit now if we it failed (or wasn't found), and '--version' was 91 | # passed; such an option is passed most likely to detect whether the 92 | # program is present and works. 93 | case $2 in --version|--help) exit $st;; esac 94 | 95 | # Exit code 63 means version mismatch. This often happens when the user 96 | # tries to use an ancient version of a tool on a file that requires a 97 | # minimum version. 98 | if test $st -eq 63; then 99 | msg="probably too old" 100 | elif test $st -eq 127; then 101 | # Program was missing. 102 | msg="missing on your system" 103 | else 104 | # Program was found and executed, but failed. Give up. 105 | exit $st 106 | fi 107 | 108 | perl_URL=https://www.perl.org/ 109 | flex_URL=https://github.com/westes/flex 110 | gnu_software_URL=https://www.gnu.org/software 111 | 112 | program_details () 113 | { 114 | case $1 in 115 | aclocal|automake|autoreconf) 116 | echo "The '$1' program is part of the GNU Automake package:" 117 | echo "<$gnu_software_URL/automake>" 118 | echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" 119 | echo "<$gnu_software_URL/autoconf>" 120 | echo "<$gnu_software_URL/m4/>" 121 | echo "<$perl_URL>" 122 | ;; 123 | autoconf|autom4te|autoheader) 124 | echo "The '$1' program is part of the GNU Autoconf package:" 125 | echo "<$gnu_software_URL/autoconf/>" 126 | echo "It also requires GNU m4 and Perl in order to run:" 127 | echo "<$gnu_software_URL/m4/>" 128 | echo "<$perl_URL>" 129 | ;; 130 | *) 131 | : 132 | ;; 133 | esac 134 | } 135 | 136 | give_advice () 137 | { 138 | # Normalize program name to check for. 139 | normalized_program=`echo "$1" | sed ' 140 | s/^gnu-//; t 141 | s/^gnu//; t 142 | s/^g//; t'` 143 | 144 | printf '%s\n' "'$1' is $msg." 145 | 146 | configure_deps="'configure.ac' or m4 files included by 'configure.ac'" 147 | autoheader_deps="'acconfig.h'" 148 | automake_deps="'Makefile.am'" 149 | aclocal_deps="'acinclude.m4'" 150 | case $normalized_program in 151 | aclocal*) 152 | echo "You should only need it if you modified $aclocal_deps or" 153 | echo "$configure_deps." 154 | ;; 155 | autoconf*) 156 | echo "You should only need it if you modified $configure_deps." 157 | ;; 158 | autogen*) 159 | echo "You should only need it if you modified a '.def' or '.tpl' file." 160 | echo "You may want to install the GNU AutoGen package:" 161 | echo "<$gnu_software_URL/autogen/>" 162 | ;; 163 | autoheader*) 164 | echo "You should only need it if you modified $autoheader_deps or" 165 | echo "$configure_deps." 166 | ;; 167 | automake*) 168 | echo "You should only need it if you modified $automake_deps or" 169 | echo "$configure_deps." 170 | ;; 171 | autom4te*) 172 | echo "You might have modified some maintainer files that require" 173 | echo "the 'autom4te' program to be rebuilt." 174 | ;; 175 | autoreconf*) 176 | echo "You should only need it if you modified $aclocal_deps or" 177 | echo "$automake_deps or $autoheader_deps or $automake_deps or" 178 | echo "$configure_deps." 179 | ;; 180 | bison*|yacc*) 181 | echo "You should only need it if you modified a '.y' file." 182 | echo "You may want to install the GNU Bison package:" 183 | echo "<$gnu_software_URL/bison/>" 184 | ;; 185 | help2man*) 186 | echo "You should only need it if you modified a dependency" \ 187 | "of a man page." 188 | echo "You may want to install the GNU Help2man package:" 189 | echo "<$gnu_software_URL/help2man/>" 190 | ;; 191 | lex*|flex*) 192 | echo "You should only need it if you modified a '.l' file." 193 | echo "You may want to install the Fast Lexical Analyzer package:" 194 | echo "<$flex_URL>" 195 | ;; 196 | makeinfo*) 197 | echo "You should only need it if you modified a '.texi' file, or" 198 | echo "any other file indirectly affecting the aspect of the manual." 199 | echo "You might want to install the Texinfo package:" 200 | echo "<$gnu_software_URL/texinfo/>" 201 | echo "The spurious makeinfo call might also be the consequence of" 202 | echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" 203 | echo "want to install GNU make:" 204 | echo "<$gnu_software_URL/make/>" 205 | ;; 206 | perl*) 207 | echo "You should only need it to run GNU Autoconf, GNU Automake, " 208 | echo " assorted other tools, or if you modified a Perl source file." 209 | echo "You may want to install the Perl 5 language interpreter:" 210 | echo "<$perl_URL>" 211 | ;; 212 | *) 213 | echo "You might have modified some files without having the proper" 214 | echo "tools for further handling them. Check the 'README' file, it" 215 | echo "often tells you about the needed prerequisites for installing" 216 | echo "this package. You may also peek at any GNU archive site, in" 217 | echo "case some other package contains this missing '$1' program." 218 | ;; 219 | esac 220 | program_details "$normalized_program" 221 | } 222 | 223 | give_advice "$1" | sed -e '1s/^/WARNING: /' \ 224 | -e '2,$s/^/ /' >&2 225 | 226 | # Propagate the correct exit status (expected to be 127 for a program 227 | # not found, 63 for a program that failed due to version mismatch). 228 | exit $st 229 | 230 | # Local variables: 231 | # eval: (add-hook 'before-save-hook 'time-stamp) 232 | # time-stamp-start: "scriptversion=" 233 | # time-stamp-format: "%:y-%02m-%02d.%02H" 234 | # time-stamp-time-zone: "UTC0" 235 | # time-stamp-end: "; # UTC" 236 | # End: 237 | -------------------------------------------------------------------------------- /aux-build/mkinstalldirs: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # mkinstalldirs --- make directory hierarchy 3 | 4 | scriptversion=2024-06-19.01; # UTC 5 | 6 | # Original author: Noah Friedman 7 | # Created: 1993-05-16 8 | # Public domain. 9 | # 10 | # This file is maintained in Automake, please report 11 | # bugs to or send patches to 12 | # . 13 | 14 | nl=' 15 | ' 16 | IFS=" "" $nl" 17 | errstatus=0 18 | dirmode= 19 | 20 | usage="\ 21 | Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... 22 | 23 | Create each directory DIR (with mode MODE, if specified), including all 24 | leading file name components. 25 | 26 | Report bugs to . 27 | GNU Automake home page: . 28 | General help using GNU software: ." 29 | 30 | # process command line arguments 31 | while test $# -gt 0 ; do 32 | case $1 in 33 | -h | --help | --h*) # -h for help 34 | echo "$usage" 35 | exit $? 36 | ;; 37 | -m) # -m PERM arg 38 | shift 39 | test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } 40 | dirmode=$1 41 | shift 42 | ;; 43 | --version) 44 | echo "$0 (GNU Automake) $scriptversion" 45 | exit $? 46 | ;; 47 | --) # stop option processing 48 | shift 49 | break 50 | ;; 51 | -*) # unknown option 52 | echo "$usage" 1>&2 53 | exit 1 54 | ;; 55 | *) # first non-opt arg 56 | break 57 | ;; 58 | esac 59 | done 60 | 61 | for file 62 | do 63 | if test -d "$file"; then 64 | shift 65 | else 66 | break 67 | fi 68 | done 69 | 70 | case $# in 71 | 0) exit 0 ;; 72 | esac 73 | 74 | # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and 75 | # mkdir -p a/c at the same time, both will detect that a is missing, 76 | # one will create a, then the other will try to create a and die with 77 | # a "File exists" error. This is a problem when calling mkinstalldirs 78 | # from a parallel make. We use --version in the probe to restrict 79 | # ourselves to GNU mkdir, which is thread-safe. 80 | case $dirmode in 81 | '') 82 | if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then 83 | echo "mkdir -p -- $*" 84 | exec mkdir -p -- "$@" 85 | else 86 | # On NextStep and OpenStep, the 'mkdir' command does not 87 | # recognize any option. It will interpret all options as 88 | # directories to create, and then abort because '.' already 89 | # exists. 90 | test -d ./-p && rmdir ./-p 91 | test -d ./--version && rmdir ./--version 92 | fi 93 | ;; 94 | *) 95 | if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && 96 | test ! -d ./--version; then 97 | echo "umask 22" 98 | umask 22 99 | echo "mkdir -m $dirmode -p -- $*" 100 | exec mkdir -m "$dirmode" -p -- "$@" 101 | else 102 | # Clean up after NextStep and OpenStep mkdir. 103 | for d in ./-m ./-p ./--version "./$dirmode"; 104 | do 105 | test -d $d && rmdir $d 106 | done 107 | fi 108 | ;; 109 | esac 110 | 111 | echo "umask 22" 112 | umask 22 113 | 114 | for file 115 | do 116 | case $file in 117 | /*) pathcomp=/ ;; 118 | *) pathcomp= ;; 119 | esac 120 | oIFS=$IFS 121 | IFS=/ 122 | set fnord $file 123 | shift 124 | IFS=$oIFS 125 | 126 | for d 127 | do 128 | test "x$d" = x && continue 129 | 130 | pathcomp=$pathcomp$d 131 | case $pathcomp in 132 | -*) pathcomp=./$pathcomp ;; 133 | esac 134 | 135 | if test ! -d "$pathcomp"; then 136 | echo "mkdir $pathcomp" 137 | 138 | mkdir "$pathcomp" || lasterr=$? 139 | 140 | if test ! -d "$pathcomp"; then 141 | errstatus=$lasterr 142 | fi 143 | fi 144 | 145 | pathcomp=$pathcomp/ 146 | done 147 | 148 | if test ! -z "$dirmode"; then 149 | echo "chmod $dirmode $file" 150 | chmod "$dirmode" "$file" || errstatus=$? 151 | fi 152 | done 153 | 154 | exit $errstatus 155 | 156 | # Local Variables: 157 | # mode: shell-script 158 | # sh-indentation: 2 159 | # eval: (add-hook 'before-save-hook 'time-stamp) 160 | # time-stamp-start: "scriptversion=" 161 | # time-stamp-format: "%:y-%02m-%02d.%02H" 162 | # time-stamp-time-zone: "UTC0" 163 | # time-stamp-end: "; # UTC" 164 | # End: 165 | -------------------------------------------------------------------------------- /aux-build/test-driver: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # test-driver - basic testsuite driver script. 3 | 4 | scriptversion=2024-06-19.01; # UTC 5 | 6 | # Copyright (C) 2011-2024 Free Software Foundation, Inc. 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2, or (at your option) 11 | # any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | # As a special exception to the GNU General Public License, if you 22 | # distribute this file as part of a program that contains a 23 | # configuration script generated by Autoconf, you may include it under 24 | # the same distribution terms that you use for the rest of that program. 25 | 26 | # This file is maintained in Automake, please report 27 | # bugs to or send patches to 28 | # . 29 | 30 | # Make unconditional expansion of undefined variables an error. This 31 | # helps a lot in preventing typo-related bugs. 32 | set -u 33 | 34 | usage_error () 35 | { 36 | echo "$0: $*" >&2 37 | print_usage >&2 38 | exit 2 39 | } 40 | 41 | print_usage () 42 | { 43 | cat <. 55 | GNU Automake home page: . 56 | General help using GNU software: . 57 | END 58 | } 59 | 60 | test_name= # Used for reporting. 61 | log_file= # Where to save the output of the test script. 62 | trs_file= # Where to save the metadata of the test run. 63 | expect_failure=no 64 | color_tests=no 65 | collect_skipped_logs=yes 66 | enable_hard_errors=yes 67 | while test $# -gt 0; do 68 | case $1 in 69 | --help) print_usage; exit $?;; 70 | --version) echo "test-driver (GNU Automake) $scriptversion"; exit $?;; 71 | --test-name) test_name=$2; shift;; 72 | --log-file) log_file=$2; shift;; 73 | --trs-file) trs_file=$2; shift;; 74 | --color-tests) color_tests=$2; shift;; 75 | --collect-skipped-logs) collect_skipped_logs=$2; shift;; 76 | --expect-failure) expect_failure=$2; shift;; 77 | --enable-hard-errors) enable_hard_errors=$2; shift;; 78 | --) shift; break;; 79 | -*) usage_error "invalid option: '$1'";; 80 | *) break;; 81 | esac 82 | shift 83 | done 84 | 85 | missing_opts= 86 | test x"$test_name" = x && missing_opts="$missing_opts --test-name" 87 | test x"$log_file" = x && missing_opts="$missing_opts --log-file" 88 | test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" 89 | if test x"$missing_opts" != x; then 90 | usage_error "the following mandatory options are missing:$missing_opts" 91 | fi 92 | 93 | if test $# -eq 0; then 94 | usage_error "missing argument" 95 | fi 96 | 97 | if test $color_tests = yes; then 98 | # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. 99 | red='' # Red. 100 | grn='' # Green. 101 | lgn='' # Light green. 102 | blu='' # Blue. 103 | mgn='' # Magenta. 104 | std='' # No color. 105 | else 106 | red= grn= lgn= blu= mgn= std= 107 | fi 108 | 109 | do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' 110 | trap "st=129; $do_exit" 1 111 | trap "st=130; $do_exit" 2 112 | trap "st=141; $do_exit" 13 113 | trap "st=143; $do_exit" 15 114 | 115 | # Test script is run here. We create the file first, then append to it, 116 | # to ameliorate tests themselves also writing to the log file. Our tests 117 | # don't, but others can (automake bug#35762). 118 | : >"$log_file" 119 | "$@" >>"$log_file" 2>&1 120 | estatus=$? 121 | 122 | if test $enable_hard_errors = no && test $estatus -eq 99; then 123 | tweaked_estatus=1 124 | else 125 | tweaked_estatus=$estatus 126 | fi 127 | 128 | case $tweaked_estatus:$expect_failure in 129 | 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 130 | 0:*) col=$grn res=PASS recheck=no gcopy=no;; 131 | 77:*) col=$blu res=SKIP recheck=no gcopy=$collect_skipped_logs;; 132 | 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; 133 | *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; 134 | *:*) col=$red res=FAIL recheck=yes gcopy=yes;; 135 | esac 136 | 137 | # Report the test outcome and exit status in the logs, so that one can 138 | # know whether the test passed or failed simply by looking at the '.log' 139 | # file, without the need of also peaking into the corresponding '.trs' 140 | # file (automake bug#11814). 141 | echo "$res $test_name (exit status: $estatus)" >>"$log_file" 142 | 143 | # Report outcome to console. 144 | echo "${col}${res}${std}: $test_name" 145 | 146 | # Register the test result, and other relevant metadata. 147 | echo ":test-result: $res" > $trs_file 148 | echo ":global-test-result: $res" >> $trs_file 149 | echo ":recheck: $recheck" >> $trs_file 150 | echo ":copy-in-global-log: $gcopy" >> $trs_file 151 | 152 | # Local Variables: 153 | # mode: shell-script 154 | # sh-indentation: 2 155 | # eval: (add-hook 'before-save-hook 'time-stamp) 156 | # time-stamp-start: "scriptversion=" 157 | # time-stamp-format: "%:y-%02m-%02d.%02H" 158 | # time-stamp-time-zone: "UTC0" 159 | # time-stamp-end: "; # UTC" 160 | # End: 161 | -------------------------------------------------------------------------------- /aux-build/ylwrap: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # ylwrap - wrapper for lex/yacc invocations. 3 | 4 | scriptversion=2024-06-19.01; # UTC 5 | 6 | # Copyright (C) 1996-2024 Free Software Foundation, Inc. 7 | # 8 | # Written by Tom Tromey . 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | 23 | # As a special exception to the GNU General Public License, if you 24 | # distribute this file as part of a program that contains a 25 | # configuration script generated by Autoconf, you may include it under 26 | # the same distribution terms that you use for the rest of that program. 27 | 28 | # This file is maintained in Automake, please report 29 | # bugs to or send patches to 30 | # . 31 | 32 | get_dirname () 33 | { 34 | case $1 in 35 | */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; 36 | # Otherwise, we want the empty string (not "."). 37 | esac 38 | } 39 | 40 | # guard FILE 41 | # ---------- 42 | # The CPP macro used to guard inclusion of FILE. 43 | guard () 44 | { 45 | printf '%s\n' "$1" \ 46 | | sed \ 47 | -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ 48 | -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ 49 | -e 's/__*/_/g' 50 | } 51 | 52 | # quote_for_sed [STRING] 53 | # ---------------------- 54 | # Return STRING (or stdin) quoted to be used as a sed pattern. 55 | quote_for_sed () 56 | { 57 | case $# in 58 | 0) cat;; 59 | 1) printf '%s\n' "$1";; 60 | esac \ 61 | | sed -e 's|[][\\.*]|\\&|g' 62 | } 63 | 64 | case "$1" in 65 | '') 66 | echo "$0: No files given. Try '$0 --help' for more information." 1>&2 67 | exit 1 68 | ;; 69 | -h|--h*) 70 | cat <<\EOF 71 | Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... 72 | 73 | Wrapper for lex/yacc invocations, renaming files as desired. 74 | 75 | INPUT is the input file 76 | OUTPUT is one file PROG generates 77 | DESIRED is the file we actually want instead of OUTPUT 78 | PROGRAM is program to run 79 | ARGS are passed to PROG 80 | 81 | Any number of OUTPUT,DESIRED pairs may be used. 82 | 83 | Report bugs to . 84 | GNU Automake home page: . 85 | General help using GNU software: . 86 | EOF 87 | exit $? 88 | ;; 89 | -v|--v*) 90 | echo "ylwrap (GNU Automake) $scriptversion" 91 | exit $? 92 | ;; 93 | esac 94 | 95 | 96 | # The input. 97 | input=$1 98 | shift 99 | # We'll later need for a correct munging of "#line" directives. 100 | input_sub_rx=`get_dirname "$input" | quote_for_sed` 101 | case $input in 102 | [\\/]* | ?:[\\/]*) 103 | # Absolute path; do nothing. 104 | ;; 105 | *) 106 | # Relative path. Make it absolute. 107 | input=`pwd`/$input 108 | ;; 109 | esac 110 | input_rx=`get_dirname "$input" | quote_for_sed` 111 | 112 | # Since DOS filename conventions don't allow two dots, 113 | # the DOS version of Bison writes out y_tab.c instead of y.tab.c 114 | # and y_tab.h instead of y.tab.h. Test to see if this is the case. 115 | y_tab_nodot=false 116 | if test -f y_tab.c || test -f y_tab.h; then 117 | y_tab_nodot=true 118 | fi 119 | 120 | # The parser itself, the first file, is the destination of the .y.c 121 | # rule in the Makefile. 122 | parser=$1 123 | 124 | # A sed program to s/FROM/TO/g for all the FROM/TO so that, for 125 | # instance, we rename #include "y.tab.h" into #include "parse.h" 126 | # during the conversion from y.tab.c to parse.c. 127 | sed_fix_filenames= 128 | 129 | # Also rename header guards, as Bison 2.7 for instance uses its header 130 | # guard in its implementation file. 131 | sed_fix_header_guards= 132 | 133 | while test $# -ne 0; do 134 | if test x"$1" = x"--"; then 135 | shift 136 | break 137 | fi 138 | from=$1 139 | # Handle y_tab.c and y_tab.h output by DOS 140 | if $y_tab_nodot; then 141 | case $from in 142 | "y.tab.c") from=y_tab.c;; 143 | "y.tab.h") from=y_tab.h;; 144 | esac 145 | fi 146 | shift 147 | to=$1 148 | shift 149 | sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" 150 | sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" 151 | done 152 | 153 | # The program to run. 154 | prog=$1 155 | shift 156 | # Make any relative path in $prog absolute. 157 | case $prog in 158 | [\\/]* | ?:[\\/]*) ;; 159 | *[\\/]*) prog=`pwd`/$prog ;; 160 | esac 161 | 162 | dirname=ylwrap$$ 163 | do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' 164 | trap "ret=129; $do_exit" 1 165 | trap "ret=130; $do_exit" 2 166 | trap "ret=141; $do_exit" 13 167 | trap "ret=143; $do_exit" 15 168 | mkdir $dirname || exit 1 169 | 170 | cd $dirname 171 | 172 | case $# in 173 | 0) "$prog" "$input" ;; 174 | *) "$prog" "$@" "$input" ;; 175 | esac 176 | ret=$? 177 | 178 | if test $ret -eq 0; then 179 | for from in * 180 | do 181 | to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` 182 | if test -f "$from"; then 183 | # If $2 is an absolute path name, then just use that, 184 | # otherwise prepend '../'. 185 | case $to in 186 | [\\/]* | ?:[\\/]*) target=$to;; 187 | *) target=../$to;; 188 | esac 189 | 190 | # Do not overwrite unchanged header files to avoid useless 191 | # recompilations. Always update the parser itself: it is the 192 | # destination of the .y.c rule in the Makefile. Divert the 193 | # output of all other files to a temporary file so we can 194 | # compare them to existing versions. 195 | if test $from != $parser; then 196 | realtarget=$target 197 | target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` 198 | fi 199 | 200 | # Munge "#line" or "#" directives. Don't let the resulting 201 | # debug information point at an absolute srcdir. Use the real 202 | # output file name, not yy.lex.c for instance. Adjust the 203 | # include guards too. 204 | sed -e "/^#/!b" \ 205 | -e "s|$input_rx|$input_sub_rx|" \ 206 | -e "$sed_fix_filenames" \ 207 | -e "$sed_fix_header_guards" \ 208 | "$from" >"$target" || ret=$? 209 | 210 | # Check whether files must be updated. 211 | if test "$from" != "$parser"; then 212 | if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then 213 | echo "$to is unchanged" 214 | rm -f "$target" 215 | else 216 | echo "updating $to" 217 | mv -f "$target" "$realtarget" 218 | fi 219 | fi 220 | else 221 | # A missing file is only an error for the parser. This is a 222 | # blatant hack to let us support using "yacc -d". If -d is not 223 | # specified, don't fail when the header file is "missing". 224 | if test "$from" = "$parser"; then 225 | ret=1 226 | fi 227 | fi 228 | done 229 | fi 230 | 231 | # Remove the directory. 232 | cd .. 233 | rm -rf $dirname 234 | 235 | exit $ret 236 | 237 | # Local Variables: 238 | # mode: shell-script 239 | # sh-indentation: 2 240 | # eval: (add-hook 'before-save-hook 'time-stamp) 241 | # time-stamp-start: "scriptversion=" 242 | # time-stamp-format: "%:y-%02m-%02d.%02H" 243 | # time-stamp-time-zone: "UTC0" 244 | # time-stamp-end: "; # UTC" 245 | # End: 246 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Process this file with autoconf to produce a configure script. 2 | AC_INIT([cbase],[1.4],[hyperrealm@gmail.com]) 3 | AC_CONFIG_AUX_DIR([aux-build]) 4 | AC_CONFIG_MACRO_DIR([m4]) 5 | AM_INIT_AUTOMAKE 6 | AC_CONFIG_HEADERS([config.h]) 7 | 8 | # Checks for programs. 9 | AC_PROG_CC 10 | LT_INIT 11 | 12 | # Checks for libraries. 13 | 14 | AC_CHECK_LIB(crypt, crypt) 15 | AC_CHECK_LIB(dl, dlopen) 16 | AC_CHECK_LIB(pthread, pthread_create) 17 | AC_CHECK_LIB(rt, sem_open) 18 | AC_CHECK_LIB(rt, shm_open) 19 | AC_CHECK_LIB(socket, socket) 20 | AC_CHECK_LIB(nsl, gethostbyaddr) 21 | AC_CHECK_LIB(util, openpty) 22 | 23 | # Checks for header files. 24 | AC_HEADER_DIRENT 25 | AC_CHECK_INCLUDES_DEFAULT 26 | AC_PROG_EGREP 27 | 28 | AC_HEADER_SYS_WAIT 29 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stdlib.h string.h sys/file.h sys/ioctl.h sys/time.h termios.h unistd.h stdint.h crypt.h stropts.h sys/socket.h]) 30 | 31 | # Checks for typedefs, structures, and compiler characteristics. 32 | AC_C_CONST 33 | AC_TYPE_UID_T 34 | AC_C_INLINE 35 | AC_TYPE_MODE_T 36 | AC_TYPE_OFF_T 37 | AC_TYPE_PID_T 38 | AC_TYPE_SIZE_T 39 | 40 | AC_CHECK_HEADERS_ONCE([sys/time.h]) 41 | 42 | AC_STRUCT_TM 43 | AC_CHECK_MEMBERS([struct msghdr.msg_accrights, struct msghdr.msg_control],,, 44 | [#include 45 | #ifdef HAVE_SYS_SOCKET_H 46 | #include 47 | #endif]) 48 | 49 | dnl Checks for POSIX socket types 50 | 51 | AH_TEMPLATE([HAVE_TYPE_SOCKLEN_T], [Define if sys/socket.h or unistd.h defines socklen_t]) 52 | 53 | AC_MSG_CHECKING(for socklen_t in sys/socket.h or unistd.h) 54 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 55 | #include ]], [[socklen_t t;]])],[AC_DEFINE(HAVE_TYPE_SOCKLEN_T) 56 | AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)]) 57 | 58 | AH_TEMPLATE([HAVE_TYPE_IN_ADDR_T], [Define if netinet/in.h or sys/types.h defines in_addr_t]) 59 | 60 | AC_MSG_CHECKING(for in_addr_t in netinet/in.h or sys/types.h) 61 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 62 | #include ]], [[in_addr_t t;]])],[AC_DEFINE(HAVE_TYPE_IN_ADDR_T) 63 | AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)]) 64 | 65 | AH_TEMPLATE([HAVE_TYPE_IN_PORT_T], [Define if netinet/in.h or sys/types.h defines in_port_t]) 66 | 67 | AC_MSG_CHECKING(for in_port_t in netinet/in.h or sys/types.h) 68 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 69 | #include ]], [[in_port_t t;]])],[AC_DEFINE(HAVE_TYPE_IN_PORT_T) 70 | AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)]) 71 | 72 | dnl Checks for constant CMSG_SPACE 73 | 74 | AC_MSG_CHECKING([for constant CMSG_SPACE]) 75 | AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ 76 | #if HAVE_SYS_SOCKET_H 77 | #include 78 | #endif 79 | 80 | int a[CMSG_SPACE(int)]; 81 | ]])], [ 82 | AC_MSG_RESULT(yes) 83 | AC_DEFINE(HAVE_CONSTANT_CMSG_SPACE, 1, [Define to 1 if CMSG_SPACE is constant]) 84 | ], [ 85 | AC_MSG_RESULT(no) 86 | ]) 87 | 88 | dnl Checks for gethostbyname_r & friends 89 | 90 | AC_SEARCH_LIBS(gethostbyname_r, [socket nsl]) 91 | AC_SEARCH_LIBS(getservbyname_r, [socket nsl]) 92 | 93 | AH_TEMPLATE([HAVE_GETxxxxBYyyyy_R_POSIX], [Define if POSIX-style getXXXXbyYYYY_r functions are available.]) 94 | 95 | AC_MSG_CHECKING([for POSIX-style gethostbyXXXX_r and getservbyXXXX_r]) 96 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[ 97 | #define _POSIX_PTHREAD_SEMANTICS 98 | #include 99 | #include 100 | ]], [[ 101 | struct hostent *he; 102 | struct servent *se; 103 | 104 | he = gethostbyname_r((const char *)NULL, (struct hostent *)NULL, 105 | (char *)NULL, (int)0, (struct hostent **)NULL, (int *)NULL); 106 | he = gethostbyaddr_r((const char *)NULL, (int)0, (int)0, 107 | (struct hostent *)NULL, (char *)NULL, (int)0, (struct hostent **)NULL, 108 | (int *)NULL); 109 | 110 | se = getservbyname_r((const char *)NULL, (const char *)NULL, 111 | (struct servent *)NULL, (char *)NULL, (int)0, (struct servent **)NULL); 112 | se = getservbyport_r((int)0, (const char *)NULL, 113 | (struct servent *)NULL, (char *)NULL, (int)0, (struct servent **)NULL); 114 | ]])],[AC_DEFINE(HAVE_GETxxxxBYyyyy_R_POSIX) 115 | AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no) 116 | ]) 117 | 118 | AH_TEMPLATE([HAVE_GETxxxxBYyyyy_R_SUN], [Define if Solaris-style getXXXXbyYYYY_r functions are available.]) 119 | 120 | AC_MSG_CHECKING([for Solaris-style gethostbyXXXX_r and getservbyXXXX_r]) 121 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[ 122 | #define _POSIX_PTHREAD_SEMANTICS 123 | #include 124 | #include 125 | ]], [[ struct hostent *he; 126 | struct servent *se; 127 | 128 | he = gethostbyname_r((const char *)NULL, (struct hostent *)NULL, 129 | (char *)NULL, (int)0, (int *)NULL); 130 | he = gethostbyaddr_r((const char *)NULL, (int)0, (int)0, 131 | (struct hostent *)NULL, (char *)NULL, (int)0, (int *)NULL); 132 | 133 | se = getservbyname_r((const char *)NULL, (const char *)NULL, 134 | (struct servent *)NULL, (char *)NULL, (int)0); 135 | se = getservbyport_r((int)0, (const char *)NULL, 136 | (struct servent *)NULL, (char *)NULL, (int)0); 137 | ]])],[AC_DEFINE(HAVE_GETxxxxBYyyyy_R_SUN) 138 | AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no) 139 | ]) 140 | 141 | dnl Checks for library functions. 142 | 143 | AC_FUNC_CLOSEDIR_VOID 144 | AC_FUNC_FORK 145 | AC_FUNC_LSTAT 146 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK 147 | AC_FUNC_MKTIME 148 | AC_FUNC_MMAP 149 | AC_FUNC_REALLOC 150 | AC_FUNC_SELECT_ARGTYPES 151 | AC_FUNC_STAT 152 | AC_FUNC_STRFTIME 153 | AC_FUNC_VPRINTF 154 | AC_CHECK_FUNCS([dup2 flockfile ftruncate getcwd inet_ntoa localtime_r memmove memset mkdir munmap pathconf select socket strchr strerror strpbrk uname getgrnam_r sranddev]) 155 | 156 | dnl AC_CONFIG_FILES([]) 157 | AC_CONFIG_FILES([Makefile lib/Makefile lib/libcbase.pc lib/libcbase_mt.pc 158 | doc/Makefile]) 159 | AC_OUTPUT 160 | 161 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | info_TEXINFOS = cbase.texi 3 | cbase_TEXINFOS = LGPL.texi 4 | 5 | html: 6 | $(MAKEINFO) --html --no-split cbase.texi 7 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: cbase 2 | description: C Foundation Library 3 | show_downloads: true 4 | theme: jekyll-theme-cayman 5 | -------------------------------------------------------------------------------- /docs/cbase_manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperrealm/cbase/b12cf720ed43c75e26302d7959ba6608f0603c53/docs/cbase_manual.pdf -------------------------------------------------------------------------------- /docs/dist/cbase-1.4.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperrealm/cbase/b12cf720ed43c75e26302d7959ba6608f0603c53/docs/dist/cbase-1.4.tar.gz -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | *Cbase* is a C library of useful functions that simplify systems 2 | software development on System V UNIX. The library includes routines for 3 | memory management, string parsing, filesystem traversal, subprocess 4 | execution, I/O, as well as implementations of common data structures 5 | such as linked lists, hash tables, stacks, and queues. The library also 6 | includes a high-level interface to Berkeley sockets, and an 7 | implementation of a scheduler which has functionality very similar to 8 | that of the *cron* daemon 9 | 10 | ## Documentation 11 | 12 | Documentation is included in the distribution 13 | in the form of a _texinfo_ manual. The documentation is 14 | also available in the following formats: 15 | 16 | - [HTML](cbase_manual.html) 17 | - [PDF](cbase_manual.pdf) 18 | 19 | ## License 20 | 21 | *Cbase* is distributed under the terms of the [GNU Lesser General 22 | Public License](http://www.gnu.org/licenses/lgpl.html). 23 | 24 | ## Downloads 25 | 26 | Download *cbase* now! Source code and full documentation are 27 | included. 28 | 29 |
30 | cbase-1.4.tar.gz 31 |
32 | -------------------------------------------------------------------------------- /lib/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | lib_LTLIBRARIES = libcbase.la libcbase_mt.la 3 | 4 | # Versioning rules ( C:R:A ) 5 | # 1. Start with version 0:0:0. 6 | # 2. If the library source code has changed at all, incremement R. 7 | # 3. If any interfaces have been added, removed, or changed, increment C and 8 | # set R to 0. 9 | # 4. If any interfaces have been added, increment A. 10 | # 5. If any interfaces have been removed, set A to 0. 11 | # For more info see page 27 of the GNU Libtool Manual. 12 | 13 | VERINFO = -version-info 9:0:0 14 | 15 | libcbase_la_LDFLAGS = $(VERINFO) 16 | libcbase_mt_la_LDFLAGS = $(VERINFO) 17 | 18 | libsrc = bitstring.c btree.c byteord.c darray.c debug.c dlobject.c dstring.c \ 19 | error.c except.c exec.c file.c filedesc.c hashtab.c hex.c \ 20 | io.c linklist.c log.c memfile.c memory.c netinfo.c pty.c random.c \ 21 | sched.c sem.c shmem.c signals.c sockctl.c sockio.c strings.c \ 22 | strbuf.c system.c time.c timer.c tty.c vector.c version.c \ 23 | netcommon.h getXXbyYY_r.c getXXbyYY_r.h mempool.c 24 | 25 | libinc = cbase/cbase.h cbase/data.h cbase/defs.h cbase/cerrno.h \ 26 | cbase/except.h cbase/ipc.h cbase/net.h cbase/sched.h \ 27 | cbase/system.h cbase/util.h cbase/version.h 28 | 29 | libcbase_la_SOURCES = $(libsrc) 30 | 31 | libcbase_mt_la_SOURCES = $(libsrc) 32 | 33 | libcbase_la_LIBADD = 34 | 35 | libcflags = -Wall -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -I. 36 | 37 | libcbase_la_CFLAGS = $(libcflags) 38 | 39 | libcbase_mt_la_CFLAGS = $(libcflags) -DTHREADED_LIBRARY 40 | cbaseincludedir = $(includedir)/cbase 41 | 42 | cbaseinclude_HEADERS = $(libinc) 43 | 44 | pkgconfigdir = $(libdir)/pkgconfig 45 | pkgconfig_DATA = libcbase.pc libcbase_mt.pc 46 | -------------------------------------------------------------------------------- /lib/bitstring.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* Local headers */ 28 | 29 | #include "cbase/defs.h" 30 | #include "cbase/util.h" 31 | #include "cbase/system.h" 32 | 33 | /* Macros */ 34 | 35 | #define _C_bitstring_byte_offset(bit) \ 36 | ((bit) >> 3) 37 | 38 | #define _C_bitstring_byte_mask(bit) \ 39 | (c_byte_t)(1 << ((bit) & 0x7)) 40 | 41 | #define _C_bitstring_getsize(nbits) \ 42 | (size_t)((((nbits) - 1) >> 3) + 1) 43 | 44 | /* Functions */ 45 | 46 | c_bitstring_t *C_bitstring_create(uint_t nbits) 47 | { 48 | c_bitstring_t *bs; 49 | int len = _C_bitstring_getsize(nbits); 50 | 51 | if(len < 1) 52 | return(NULL); 53 | 54 | bs = C_new(c_bitstring_t); 55 | bs->length = len; 56 | bs->nbits = nbits; 57 | bs->bits = C_newa(len, c_byte_t); 58 | 59 | return(bs); 60 | } 61 | 62 | /* 63 | */ 64 | 65 | c_bool_t C_bitstring_destroy(c_bitstring_t *bs) 66 | { 67 | if(! bs) 68 | return(FALSE); 69 | 70 | C_free(bs->bits); 71 | C_free(bs); 72 | 73 | return(TRUE); 74 | } 75 | 76 | /* 77 | */ 78 | 79 | c_bool_t C_bitstring_compare(c_bitstring_t *bs1, c_bitstring_t *bs2) 80 | { 81 | int r = 0, i; 82 | c_byte_t *p, *q; 83 | 84 | if(! bs1 || ! bs2) 85 | return(FALSE); 86 | 87 | if(bs1->nbits != bs2->nbits) 88 | return(FALSE); 89 | 90 | for(i = bs1->length, p = bs1->bits, q = bs2->bits; i--; ++i, ++p, ++q) 91 | r |= ((*p & *q) != 0); 92 | 93 | return(r != 0); 94 | } 95 | 96 | /* 97 | */ 98 | 99 | c_bool_t C_bitstring_clear(c_bitstring_t *bs, uint_t bit) 100 | { 101 | c_byte_t *b; 102 | 103 | if(! bs) 104 | return(FALSE); 105 | 106 | b = &(bs->bits[_C_bitstring_byte_offset(bit)]); 107 | *b &= ~(_C_bitstring_byte_mask(bit)); 108 | 109 | return(TRUE); 110 | } 111 | 112 | /* 113 | */ 114 | 115 | c_bool_t C_bitstring_set(c_bitstring_t *bs, uint_t bit) 116 | { 117 | c_byte_t *b; 118 | 119 | if(! bs) 120 | return(FALSE); 121 | 122 | b = &(bs->bits[_C_bitstring_byte_offset(bit)]); 123 | *b |= _C_bitstring_byte_mask(bit); 124 | 125 | return(TRUE); 126 | } 127 | 128 | /* 129 | */ 130 | 131 | c_bool_t C_bitstring_clear_range(c_bitstring_t *bs, uint_t sbit, uint_t ebit) 132 | { 133 | uint_t sbyte, ebyte; 134 | 135 | if(!bs || (ebit < sbit)) 136 | return(FALSE); 137 | 138 | sbyte = _C_bitstring_byte_offset(sbit); 139 | ebyte = _C_bitstring_byte_offset(ebit); 140 | 141 | if(sbyte == ebyte) 142 | { 143 | bs->bits[sbyte] &= ((0xFF >> (8 - (sbit & 0x07))) 144 | | (0xFF << ((ebit & 0x07) + 1))); 145 | } 146 | else 147 | { 148 | bs->bits[sbyte] &= 0xFF >> (8 - (sbit & 0x07)); 149 | 150 | while(++sbyte < ebyte) 151 | bs->bits[sbyte] = 0; 152 | 153 | bs->bits[ebyte] &= 0xFF << ((ebit & 0x07) + 1); 154 | } 155 | 156 | return(TRUE); 157 | } 158 | 159 | /* 160 | */ 161 | 162 | c_bool_t C_bitstring_set_range(c_bitstring_t *bs, uint_t sbit, uint_t ebit) 163 | { 164 | uint_t sbyte, ebyte; 165 | 166 | if(!bs || (ebit < sbit)) 167 | return(FALSE); 168 | 169 | sbyte = _C_bitstring_byte_offset(sbit); 170 | ebyte = _C_bitstring_byte_offset(ebit); 171 | 172 | if(sbyte == ebyte) 173 | { 174 | bs->bits[sbyte] |= ((0xFF << (sbit & 0x07)) 175 | & (0xFF >> (7 - (ebit & 0x07)))); 176 | } 177 | else 178 | { 179 | bs->bits[sbyte] |= (0xFF << (sbit & 0x07)); 180 | 181 | while(++sbyte < ebyte) 182 | bs->bits[sbyte] = 0xFF; 183 | 184 | bs->bits[ebyte] |= 0xFF >> (7 - (ebit & 0x07)); 185 | } 186 | 187 | return(TRUE); 188 | } 189 | 190 | /* 191 | */ 192 | 193 | c_bool_t C_bitstring_isset(c_bitstring_t *bs, uint_t bit) 194 | { 195 | uint_t b; 196 | 197 | if(! bs) 198 | return(FALSE); 199 | 200 | b = bs->bits[_C_bitstring_byte_offset(bit)]; 201 | 202 | return((b & (_C_bitstring_byte_mask(bit))) != 0); 203 | } 204 | 205 | /* end of source file */ 206 | -------------------------------------------------------------------------------- /lib/byteord.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | 32 | /* Local headers */ 33 | 34 | #include "cbase/defs.h" 35 | #include "cbase/system.h" 36 | 37 | /* Structs and unions */ 38 | 39 | union un32 40 | { 41 | float f; 42 | uint32_t l; 43 | }; 44 | 45 | union un64 46 | { 47 | double d; 48 | uint64_t ll; 49 | }; 50 | 51 | /* File scope variables */ 52 | 53 | #define __C_byteord_big_endian ((c_bool_t)(htonl(1) == 1)) 54 | 55 | /* Functions */ 56 | 57 | uint16_t C_byteord_htons(uint16_t val) 58 | { 59 | return(htons(val)); 60 | } 61 | 62 | /* 63 | */ 64 | 65 | uint16_t C_byteord_ntohs(uint16_t val) 66 | { 67 | return(ntohs(val)); 68 | } 69 | 70 | /* 71 | */ 72 | 73 | uint32_t C_byteord_htonl(uint32_t val) 74 | { 75 | return(htonl(val)); 76 | } 77 | 78 | /* 79 | */ 80 | 81 | uint32_t C_byteord_ntohl(uint32_t val) 82 | { 83 | return(ntohl(val)); 84 | } 85 | 86 | /* 87 | */ 88 | 89 | uint64_t C_byteord_htonll(uint64_t val) 90 | { 91 | if(__C_byteord_big_endian) 92 | return(val); 93 | else 94 | return((((uint64_t)htonl((uint32_t)val)) << 32) 95 | + htonl((uint32_t)(val >> 32))); 96 | } 97 | 98 | /* 99 | */ 100 | 101 | uint64_t C_byteord_ntohll(uint64_t val) 102 | { 103 | if(__C_byteord_big_endian) 104 | return(val); 105 | else 106 | return((((uint64_t)ntohl((uint32_t)val)) << 32) 107 | + ntohl((uint32_t)(val >> 32))); 108 | } 109 | 110 | /* 111 | */ 112 | 113 | float C_byteord_htonf(float val) 114 | { 115 | union un32 u; 116 | 117 | u.f = val; 118 | u.l = C_byteord_htonl(u.l); 119 | 120 | return(u.f); 121 | } 122 | 123 | /* 124 | */ 125 | 126 | float C_byteord_ntohf(float val) 127 | { 128 | union un32 u; 129 | 130 | u.f = val; 131 | u.l = C_byteord_ntohl(u.l); 132 | 133 | return(u.f); 134 | } 135 | 136 | /* 137 | */ 138 | 139 | double C_byteord_htond(double val) 140 | { 141 | union un64 u; 142 | 143 | u.d = val; 144 | u.ll = C_byteord_htonll(u.ll); 145 | 146 | return(u.d); 147 | } 148 | 149 | /* 150 | */ 151 | 152 | double C_byteord_ntohd(double val) 153 | { 154 | union un64 u; 155 | 156 | u.d = val; 157 | u.ll = C_byteord_ntohll(u.ll); 158 | 159 | return(u.d); 160 | } 161 | 162 | /* end of source file */ 163 | -------------------------------------------------------------------------------- /lib/cbase/cbase.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_h 24 | #define __cbase_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #endif /* __cbase_h */ 38 | 39 | /* end of library header */ 40 | -------------------------------------------------------------------------------- /lib/cbase/cerrno.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_errno_h 24 | #define __cbase_errno_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | #include 31 | 32 | #define C_EFAILED -1 /* general failure */ 33 | #define C_EOK 0 /* success (no error) */ 34 | #define C_EINVAL 1 /* invalid argument(s) */ 35 | #define C_ESOCKET 2 /* socket() error */ 36 | #define C_EBADSTATE 3 /* call not valid in this state */ 37 | #define C_EADDRINFO 4 /* unable to resolve network address */ 38 | #define C_EBIND 5 /* bind() error */ 39 | #define C_EBLOCKED 6 /* operation would block */ 40 | #define C_EACCEPT 7 /* accept() error */ 41 | #define C_EBADTYPE 8 /* wrong socket type for operation */ 42 | #define C_ELISTEN 9 /* listen() error */ 43 | #define C_ESOCKINFO 10 /* unable to obtain socket info */ 44 | #define C_EFCNTL 11 /* fcntl() error */ 45 | #define C_ELOSTCONN 12 /* connection to peer lost */ 46 | #define C_EFDOPEN 13 /* fdopen() error */ 47 | #define C_ECONNECT 14 /* connect() error */ 48 | #define C_ENOCONN 15 /* no connection available */ 49 | #define C_ESEND 16 /* send() error */ 50 | #define C_ERECV 17 /* recv() error */ 51 | #define C_EMSG2BIG 18 /* UDP message too big */ 52 | #define C_ESENDTO 19 /* sendto() error */ 53 | #define C_ERECVFROM 20 /* recvfrom() error */ 54 | #define C_ETIMEOUT 21 /* connection or I/O timed out */ 55 | #define C_ESVCINFO 22 /* unable to obtain service info */ 56 | #define C_EFORK 23 /* unable to fork */ 57 | #define C_ETBLFULL 24 /* table full (depends on context) */ 58 | #define C_ESELECT 25 /* select() error */ 59 | #define C_EIOCTL 26 /* ioctl() error */ 60 | #define C_ETCATTR 27 /* unable to get/set tty attributes */ 61 | #define C_ENOTTY 28 /* descriptor does not refer to a tty */ 62 | #define C_EGETPTY 29 /* getpty() error */ 63 | #define C_EOPEN 30 /* open() error */ 64 | #define C_EPTY 31 /* general pseudoterminal error */ 65 | #define C_EEXECV 32 /* execv() error */ 66 | #define C_ENOTIMPL 33 /* function or feature not implemented */ 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif /* __cplusplus */ 71 | 72 | #endif /* __cbase_errno_h */ 73 | 74 | /* end of header file */ 75 | -------------------------------------------------------------------------------- /lib/cbase/defs.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_defs_h 24 | #define __cbase_defs_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /* common definitions */ 38 | 39 | #ifdef TRUE 40 | #undef TRUE 41 | #endif 42 | 43 | #ifdef FALSE 44 | #undef FALSE 45 | #endif 46 | 47 | #define TRUE (1) 48 | #define FALSE (0) 49 | 50 | #ifdef NUL 51 | #undef NUL 52 | #endif 53 | 54 | #ifdef CRLF 55 | #undef CRLF 56 | #endif 57 | 58 | #define NUL '\0' 59 | #define CRLF "\r\n" 60 | 61 | typedef char c_bool_t; 62 | 63 | typedef unsigned char c_byte_t; 64 | 65 | #if !(defined(__SVR4) && defined(__sun)) 66 | typedef unsigned int uint_t; 67 | #endif 68 | 69 | typedef off_t c_pointer_t; 70 | 71 | #define C_offsetof(T, FIELD) \ 72 | ((size_t)(((void *)(&(((T *)NULL)->FIELD))) - ((void *)NULL))) 73 | 74 | #define C_lengthof(A) \ 75 | ((size_t)(sizeof(A) / sizeof(A[0]))) 76 | 77 | /* convenience macros */ 78 | 79 | #define C_max(A, B) \ 80 | (((A) > (B)) ? (A) : (B)) 81 | #define C_min(A, B) \ 82 | (((A) < (B)) ? (A) : (B)) 83 | #define C_sgn(A) \ 84 | (((A) < 0) ? -1 : ((A) ? 1 : 0)) 85 | 86 | #define C_bit_set(I, B) \ 87 | ((I) |= (1L << (B))) 88 | #define C_bit_clear(I, B) \ 89 | ((I) &= ~(1L << (B))) 90 | #define C_bit_isset(I, B) \ 91 | (((I) & (1L << (B))) ? TRUE : FALSE) 92 | 93 | /* terminal attributes */ 94 | 95 | #define C_TERMATTR_NORMAL "\033[0m" 96 | #define C_TERMATTR_BOLD "\033[1m" 97 | #define C_TERMATTR_UNDERLINE "\033[2m" 98 | #define C_TERMATTR_BLINK "\033[3m" 99 | #define C_TERMATTR_INVERSE "\033[4m" 100 | 101 | #define C_TERMATTR_FG_BLACK "\033[30m" 102 | #define C_TERMATTR_FG_RED "\033[31m" 103 | #define C_TERMATTR_FG_GREEN "\033[32m" 104 | #define C_TERMATTR_FG_YELLOW "\033[33m" 105 | #define C_TERMATTR_FG_BLUE "\033[34m" 106 | #define C_TERMATTR_FG_MAGENTA "\033[35m" 107 | #define C_TERMATTR_FG_CYAN "\033[36m" 108 | #define C_TERMATTR_FG_WHITE "\033[37m" 109 | #define C_TERMATTR_FG_DEFAULT "\033[39m" 110 | 111 | #define C_TERMATTR_BG_BLACK "\033[40m" 112 | #define C_TERMATTR_BG_RED "\033[41m" 113 | #define C_TERMATTR_BG_GREEN "\033[42m" 114 | #define C_TERMATTR_BG_YELLOW "\033[43m" 115 | #define C_TERMATTR_BG_BLUE "\033[44m" 116 | #define C_TERMATTR_BG_MAGENTA "\033[45m" 117 | #define C_TERMATTR_BG_CYAN "\033[46m" 118 | #define C_TERMATTR_BG_WHITE "\033[47m" 119 | #define C_TERMATTR_BG_DEFAULT "\033[49m" 120 | 121 | #define C_TERMATTR_CS_LINE "\033(0" 122 | #define C_TERMATTR_CS_ASCII "\033(B" 123 | 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif /* __cplusplus */ 128 | 129 | #endif /* __cbase_defs_h */ 130 | 131 | /* end of library header */ 132 | -------------------------------------------------------------------------------- /lib/cbase/except.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_except_h 24 | #define __cbase_except_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | #include 31 | 32 | /* ---------------------------------------------------------------------------- 33 | * exception handling structures 34 | * ---------------------------------------------------------------------------- 35 | */ 36 | 37 | struct C_except_context_ds { 38 | int exception; 39 | jmp_buf buf; 40 | const char *file; 41 | int line; 42 | struct C_except_context_ds *prev; 43 | }; 44 | 45 | typedef struct C_except_context_ds C_except_context_t; 46 | 47 | /* ---------------------------------------------------------------------------- 48 | * exception handling functions 49 | * ---------------------------------------------------------------------------- 50 | */ 51 | 52 | extern C_except_context_t *C_except_context_push(void); 53 | extern C_except_context_t *C_except_context_top(int exception, 54 | const char *file, int line); 55 | extern int C_except_context_pop(void); 56 | 57 | 58 | /* ---------------------------------------------------------------------------- 59 | * exception handling macros 60 | * ---------------------------------------------------------------------------- 61 | */ 62 | 63 | #define C_try \ 64 | if(setjmp(C_except_context_push()->buf) == 0) \ 65 | for(int __C_except_once = 1; \ 66 | __C_except_once; \ 67 | (void)C_except_context_pop(), --__C_except_once) 68 | 69 | #define C_catch(E) \ 70 | else for(int __C_except_once = 1, E = C_except_context_pop(); \ 71 | __C_except_once--; ) 72 | 73 | #define C_throw(E) \ 74 | longjmp(C_except_context_top(E, __FILE__, __LINE__)->buf, 1) 75 | 76 | #define C_throws(...) 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif /* __cplusplus */ 81 | 82 | #endif /* __cbase_except_h */ 83 | 84 | /* end of library header */ 85 | -------------------------------------------------------------------------------- /lib/cbase/http.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_http_h 24 | #define __cbase_http_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /* ---------------------------------------------------------------------------- 36 | * HTTP server functions 37 | * ---------------------------------------------------------------------------- 38 | */ 39 | 40 | typedef void (*c_httpsrv_handler_t)(c_socket_t * /* socket */, 41 | const char * /* uri */, 42 | c_hashtable_t * /* params */); 43 | 44 | typedef struct c_httpsrv_t 45 | { 46 | c_socket_t socket; 47 | int max_workers; 48 | int num_workers; 49 | int timeout; 50 | c_hashtable_t *handlers; 51 | c_httpsrv_handler_t dfl_handler; 52 | } c_httpsrv_t; 53 | 54 | typedef struct c_http_param_t 55 | { 56 | char *value; 57 | c_linklist_t *values; 58 | } c_http_param_t; 59 | 60 | extern c_httpsrv_t *C_httpsrv_create(in_port_t port, int max_workers, 61 | int timeout); 62 | extern void C_httpsrv_destroy(c_httpsrv_t *srv); 63 | 64 | extern void C_httpsrv_set_default_handler(c_httpsrv_t *srv, 65 | c_httpsrv_handler_t handler); 66 | 67 | extern void C_httpsrv_add_handler(c_httpsrv_t *srv, const char *uri, 68 | c_httpsrv_handler_t handler); 69 | extern void C_httpsrv_remove_handler(c_httpsrv_t *srv, const char *uri); 70 | 71 | extern void C_httpsrv_send_headers(c_socket_t *s, const char *mime_type, 72 | long length); 73 | 74 | extern c_bool_t C_httpsrv_send_status(c_socket_t *s, int status, 75 | c_bool_t errmsg); 76 | 77 | extern c_bool_t C_httpsrv_accept(c_httpsrv_t *srv); 78 | 79 | extern c_http_param_t *C_http_param_get(c_hashtable_t *params, 80 | const char *key); 81 | 82 | #define C_http_param_isarray(P) \ 83 | ((P)->values != NULL) 84 | 85 | #define C_http_param_value(P) \ 86 | ((P)->value) 87 | 88 | #define C_http_param_values(P) \ 89 | ((P)->values) 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif /* __cplusplus */ 94 | 95 | #endif /* __cbase_http_h */ 96 | 97 | /* end of library header */ 98 | -------------------------------------------------------------------------------- /lib/cbase/ipc.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_ipc_h 24 | #define __cbase_ipc_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | #include 31 | 32 | #include 33 | 34 | /* ---------------------------------------------------------------------------- 35 | * file descriptor passing 36 | * ---------------------------------------------------------------------------- 37 | */ 38 | 39 | extern c_bool_t C_fd_send(int sd, int fd); 40 | extern c_bool_t C_fd_recv(int sd, int *fd); 41 | 42 | /* ---------------------------------------------------------------------------- 43 | * terminal control 44 | * ---------------------------------------------------------------------------- 45 | */ 46 | 47 | extern c_bool_t C_tty_raw(int fd); 48 | extern c_bool_t C_tty_unraw(int fd); 49 | extern c_bool_t C_tty_store(int fd); 50 | extern c_bool_t C_tty_restore(int fd); 51 | extern c_bool_t C_tty_sane(int fd); 52 | 53 | extern c_bool_t C_tty_getsize(uint_t *columns, uint_t *rows); 54 | 55 | /* ---------------------------------------------------------------------------- 56 | * pseudoterminals 57 | * ---------------------------------------------------------------------------- 58 | */ 59 | 60 | typedef struct c_pty_t 61 | { 62 | int master_fd; 63 | int slave_fd; 64 | char pts_name[11]; 65 | } c_pty_t; 66 | 67 | extern c_pty_t *C_pty_create(void); 68 | extern c_bool_t C_pty_destroy(c_pty_t *pty); 69 | 70 | #define C_pty_master_fd(P) \ 71 | ((P)->master_fd) 72 | 73 | #define C_pty_slave_fd(P) \ 74 | ((P)->slave_fd) 75 | 76 | #define C_pty_slave_name(P) \ 77 | ((const char *)(P)->pts_name) 78 | 79 | /* ---------------------------------------------------------------------------- 80 | * signals 81 | * ---------------------------------------------------------------------------- 82 | */ 83 | 84 | #define C_SIGNAL_MIN SIGHUP 85 | 86 | #ifdef SIGXFSZ 87 | #define C_SIGNAL_MAX SIGXFSZ 88 | #else 89 | #define C_SIGNAL_MAX 31 90 | #endif 91 | 92 | typedef void (*c_sighandler_t)(int /* sig */); 93 | 94 | extern const char *C_signal_name(int sig); 95 | 96 | /* ---------------------------------------------------------------------------- 97 | * shared memory 98 | * ---------------------------------------------------------------------------- 99 | */ 100 | 101 | typedef struct c_shmem_t 102 | { 103 | int fd; 104 | void *base; 105 | size_t size; 106 | char *name; 107 | } c_shmem_t; 108 | 109 | extern c_shmem_t *C_shmem_create(const char *name, size_t size, mode_t mode); 110 | extern void C_shmem_destroy(c_shmem_t *mem); 111 | extern c_bool_t C_shmem_resize(c_shmem_t *mem, size_t size); 112 | 113 | #define /* void * */ C_shmem_base(M) \ 114 | (M)->base 115 | #define /* size_t */ C_shmem_size(M) \ 116 | (M)->size 117 | #define C_shmem_name(M) \ 118 | (const char *)((M)->name) 119 | 120 | /* ---------------------------------------------------------------------------- 121 | * counting semaphores 122 | * ---------------------------------------------------------------------------- 123 | */ 124 | 125 | typedef struct c_sem_t 126 | { 127 | sem_t *sem; 128 | char *name; 129 | int initial_value; 130 | } c_sem_t; 131 | 132 | extern c_sem_t *C_sem_create(const char *name, mode_t mode, uint_t value); 133 | extern void C_sem_destroy(c_sem_t *sem); 134 | 135 | extern c_bool_t C_sem_wait(c_sem_t *sem); 136 | extern c_bool_t C_sem_trywait(c_sem_t *sem); 137 | extern c_bool_t C_sem_post(c_sem_t *sem); 138 | extern int C_sem_value(c_sem_t *sem); 139 | 140 | #define C_sem_name(S) \ 141 | (const char *)((S)->name) 142 | 143 | #define C_sem_initial_value(S) \ 144 | ((S)->initial_value) 145 | 146 | #if defined SEM_VALUE_MAX 147 | #define C_SEM_MAX_VALUE SEM_VALUE_MAX 148 | #elif defined _SEM_VALUE_MAX 149 | #define C_SEM_MAX_VALUE _SEM_VALUE_MAX 150 | #else 151 | #define C_SEM_MAX_VALUE 32767 /* a safe default value */ 152 | #endif 153 | 154 | #ifdef __cplusplus 155 | } 156 | #endif /* __cplusplus */ 157 | 158 | #endif /* __cbase_ipc_h */ 159 | 160 | /* end of library header */ 161 | -------------------------------------------------------------------------------- /lib/cbase/sched.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_sched_h 24 | #define __cbase_sched_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | /* ---------------------------------------------------------------------------- 38 | * real-time scheduler 39 | * ---------------------------------------------------------------------------- 40 | */ 41 | 42 | #define C_SCHED_MASK_COUNT 5 43 | 44 | typedef struct c_sched_t 45 | { 46 | #if defined(__SVR4) && defined(__sun) 47 | timer_t timer; 48 | struct sigevent evp; 49 | #endif 50 | void *hook; 51 | void (*handler)(void); 52 | c_linklist_t *events; 53 | } c_sched_t; 54 | 55 | typedef struct c_schedevt_t 56 | { 57 | c_bitstring_t *mask[C_SCHED_MASK_COUNT]; 58 | c_bool_t once; 59 | void (*handler)(struct c_schedevt_t *, time_t); 60 | void (*destructor)(struct c_schedevt_t *); 61 | void *hook; 62 | c_bool_t active; 63 | uint_t id; 64 | } c_schedevt_t; 65 | 66 | extern c_bool_t C_sched_init(void); 67 | extern c_bool_t C_sched_shutdown(void); 68 | extern void C_sched_poll(void); 69 | 70 | extern c_schedevt_t *C_sched_event_create(const char *timespec, 71 | c_bool_t once, void *hook, 72 | void (*handler)(c_schedevt_t *, 73 | time_t), 74 | void (*destructor)(c_schedevt_t *), 75 | uint_t id); 76 | 77 | extern c_bool_t C_sched_event_destroy(c_schedevt_t *e); 78 | 79 | extern c_bool_t C_sched_event_activate(c_schedevt_t *e); 80 | extern c_bool_t C_sched_event_deactivate(c_schedevt_t *e); 81 | extern c_schedevt_t *C_sched_event_find(uint_t id); 82 | 83 | #define C_sched_event_data(D) \ 84 | (D)->hook 85 | 86 | #define C_sched_event_id(D) \ 87 | (D)->id 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif /* __cplusplus */ 92 | 93 | #endif /* __cbase_sched_h */ 94 | 95 | /* end of library header */ 96 | 97 | -------------------------------------------------------------------------------- /lib/cbase/version.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_version_h 24 | #define __cbase_version_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | extern const char *C_library_version(void); 31 | extern const char *C_library_info(void); 32 | extern const char **C_library_options(void); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif /* __cplusplus */ 37 | 38 | 39 | #endif /* __cbase_version_h */ 40 | 41 | /* end of library header */ 42 | -------------------------------------------------------------------------------- /lib/darray.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | 31 | /* Local headers */ 32 | 33 | #include "cbase/defs.h" 34 | #include "cbase/data.h" 35 | #include "cbase/system.h" 36 | 37 | /* Macros */ 38 | 39 | #define C_DARRAY_NBBY 8 40 | #define C_DARRAY_USED_MASK(B) ~(1 << (B)) 41 | #define C_DARRAY_FREE_MASK(B) (1 << (B)) 42 | 43 | /* Functions */ 44 | 45 | c_darray_t *C_darray_create(uint_t resize, size_t elemsz) 46 | { 47 | c_darray_t *a; 48 | char *b; 49 | uint_t i; 50 | 51 | if(resize < 1 || resize > C_DARRAY_MAX_RESIZE || !elemsz) 52 | return(NULL); 53 | 54 | a = C_new(c_darray_t); 55 | a->resize = resize * C_DARRAY_NBBY; 56 | a->iresize = resize; 57 | a->elemsz = elemsz; 58 | a->mem = (void *)C_malloc(a->resize * a->elemsz, char); 59 | a->size = a->resize; 60 | a->isize = a->iresize; 61 | a->bot = a->del_count = 0; 62 | a->free_list = C_malloc(a->iresize, char); 63 | for(i = a->iresize, b = a->free_list; i--; b++) 64 | *b = ~0; 65 | 66 | return(a); 67 | } 68 | 69 | /* 70 | */ 71 | 72 | void C_darray_destroy(c_darray_t *a) 73 | { 74 | 75 | if(!a) 76 | return; 77 | 78 | C_free(a->free_list); 79 | C_free(a->mem); 80 | C_free(a); 81 | } 82 | 83 | /* 84 | */ 85 | 86 | void *C_darray_store(c_darray_t *a, const void *data, uint_t *index) 87 | { 88 | uint_t e, bit, byte, o; 89 | char b, *bp; 90 | div_t dv; 91 | 92 | if(!a) 93 | return(NULL); 94 | 95 | if(!a->del_count) 96 | { 97 | if(a->bot == a->size) 98 | { 99 | if((a->size / C_DARRAY_NBBY) == a->isize) 100 | { 101 | o = a->isize; 102 | a->free_list = C_realloc(a->free_list, (a->isize += a->iresize), char); 103 | memset((void *)(a->free_list + o), ~0, a->iresize); 104 | } 105 | a->mem = (void *)C_realloc(a->mem, (a->size += a->resize) * a->elemsz, 106 | char); 107 | } 108 | dv = div((e = (a->bot)++), C_DARRAY_NBBY); 109 | byte = dv.quot, bit = dv.rem; 110 | } 111 | else 112 | { 113 | a->del_count--; 114 | for(byte = 0, bp = a->free_list; !*bp; byte++, bp++); 115 | b = *bp; 116 | for(bit = 0; bit < C_DARRAY_NBBY; bit++) 117 | { 118 | if(b & 1) 119 | break; 120 | b >>= 1; 121 | } 122 | e = C_DARRAY_NBBY * byte + bit; 123 | } 124 | if(index) *index = e; 125 | *(a->free_list + byte) &= C_DARRAY_USED_MASK(bit); 126 | 127 | return(memcpy((void *)(a->mem + (e * a->elemsz)), data, a->elemsz)); 128 | } 129 | 130 | /* 131 | */ 132 | 133 | void *C_darray_restore(c_darray_t *a, uint_t index) 134 | { 135 | div_t dv; 136 | 137 | if(!a) 138 | return(NULL); 139 | if(index >= a->bot) 140 | return(NULL); 141 | 142 | dv = div(index, C_DARRAY_NBBY); 143 | 144 | return((*(a->free_list + dv.quot) & C_DARRAY_FREE_MASK(dv.rem)) 145 | ? NULL : (void *)(a->mem + (index * a->elemsz))); 146 | } 147 | 148 | /* 149 | */ 150 | 151 | c_bool_t C_darray_delete(c_darray_t *a, uint_t index) 152 | { 153 | div_t dv; 154 | char *b; 155 | 156 | if(!a) 157 | return(FALSE); 158 | if(index >= a->bot) 159 | return(FALSE); 160 | dv = div(index, C_DARRAY_NBBY); 161 | b = (a->free_list + dv.quot); 162 | if(*b & C_DARRAY_FREE_MASK(dv.rem)) 163 | return(FALSE); 164 | 165 | *b |= C_DARRAY_FREE_MASK(dv.rem); 166 | a->del_count++; 167 | 168 | return(TRUE); 169 | } 170 | 171 | /* 172 | */ 173 | 174 | c_darray_t *C_darray_load(const char *path) 175 | { 176 | FILE *fp; 177 | c_darray_t *a; 178 | 179 | if(!path) 180 | return(NULL); 181 | if(!*path) 182 | return(NULL); 183 | if(!(fp = fopen(path, "r"))) 184 | return(NULL); 185 | 186 | a = C_new(c_darray_t); 187 | if(fread((void *)a, sizeof(c_darray_t), (size_t)1, fp) != 1) 188 | { 189 | C_free(a); 190 | fclose(fp); 191 | return(NULL); 192 | } 193 | 194 | a->free_list = C_newstr(a->isize); 195 | if(fread((void *)a->free_list, sizeof(char), a->isize, fp) != a->isize) 196 | { 197 | fclose(fp); 198 | C_free(a->free_list); 199 | C_free(a); 200 | return(NULL); 201 | } 202 | 203 | a->mem = (void *)C_malloc(a->size * a->elemsz, char); 204 | if(fread(a->mem, a->elemsz, a->size, fp) != a->size) 205 | { 206 | fclose(fp); 207 | C_free(a->free_list); 208 | C_free(a->mem); 209 | C_free(a); 210 | return(NULL); 211 | } 212 | 213 | fclose(fp); 214 | return(a); 215 | } 216 | 217 | /* 218 | */ 219 | 220 | c_bool_t C_darray_save(c_darray_t *a, const char *path) 221 | { 222 | FILE *fp; 223 | 224 | if(!a || !path) 225 | return(FALSE); 226 | if(!*path) 227 | return(FALSE); 228 | if(!(fp = fopen(path, "w"))) 229 | return(FALSE); 230 | 231 | if(fwrite((void *)a, sizeof(c_darray_t), (size_t)1, fp) != 1) 232 | { 233 | fclose(fp); 234 | return(FALSE); 235 | } 236 | 237 | if(fwrite((void *)a->free_list, sizeof(char), a->isize, fp) != a->isize) 238 | { 239 | fclose(fp); 240 | return(FALSE); 241 | } 242 | 243 | if(fwrite(a->mem, a->elemsz, a->size, fp) != a->size) 244 | { 245 | fclose(fp); 246 | return(FALSE); 247 | } 248 | 249 | fclose(fp); 250 | return(TRUE); 251 | } 252 | 253 | /* 254 | */ 255 | 256 | c_darray_t *C_darray_defragment(c_darray_t *a) 257 | { 258 | uint_t i; 259 | c_darray_t *n; 260 | void *e; 261 | 262 | if(!a) return(NULL); 263 | if(!a->del_count) return(a); 264 | 265 | n = C_darray_create(a->resize, a->elemsz); 266 | for(i = 0; i < a->bot; i++) 267 | if((e = C_darray_restore(a, i))) 268 | C_darray_store(n, e, NULL); 269 | C_darray_destroy(a); 270 | 271 | return(n); 272 | } 273 | 274 | /* 275 | */ 276 | 277 | c_bool_t C_darray_iterate(c_darray_t *a, 278 | c_bool_t (*iter)(void *elem, uint_t index, 279 | void *hook), 280 | uint_t index, void *hook) 281 | { 282 | char *byp, by, bil; 283 | div_t dv; 284 | uint_t i, left; 285 | void *e; 286 | 287 | if(!a || !iter) 288 | return(FALSE); 289 | if(a->bot < index) 290 | return(TRUE); 291 | dv = div(index, C_DARRAY_NBBY); 292 | 293 | for(e = a->mem + (a->elemsz * index), 294 | byp = a->free_list + dv.quot, 295 | i = 0, 296 | left = a->bot - index, 297 | bil = C_DARRAY_NBBY - dv.rem, 298 | by = *byp >> dv.rem; 299 | left--; 300 | i++, e += a->elemsz) 301 | { 302 | if(!(by & 1)) 303 | if(!iter(e, i, hook)) 304 | return(FALSE); 305 | 306 | if(!--bil) 307 | bil = C_DARRAY_NBBY, by = *(byp++); 308 | } 309 | 310 | return(TRUE); 311 | } 312 | 313 | /* end of source file */ 314 | -------------------------------------------------------------------------------- /lib/debug.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #ifdef THREADED_LIBRARY 34 | #include 35 | #endif 36 | 37 | /* Local headers */ 38 | 39 | #include "cbase/defs.h" 40 | #include "cbase/system.h" 41 | 42 | /* File scope variables */ 43 | 44 | static c_bool_t __C_debug_trace = TRUE; 45 | 46 | static FILE *__C_debug_stream = NULL; 47 | 48 | static c_bool_t __C_debug_termattr = TRUE; 49 | 50 | /* Functions */ 51 | 52 | void C_debug_set_trace(c_bool_t flag) 53 | { 54 | __C_debug_trace = flag; 55 | } 56 | 57 | /* 58 | */ 59 | 60 | void C_debug_set_stream(FILE *stream) 61 | { 62 | __C_debug_stream = stream; 63 | } 64 | 65 | /* 66 | */ 67 | 68 | void C_debug_set_termattr(c_bool_t flag) 69 | { 70 | __C_debug_termattr = flag; 71 | } 72 | 73 | /* 74 | */ 75 | 76 | void C_debug_printf_x(const char *file, int line, int severity, 77 | const char *format, ...) 78 | { 79 | va_list vp; 80 | FILE *stream = (__C_debug_stream ? __C_debug_stream : stderr); 81 | size_t l; 82 | c_bool_t nl = FALSE; 83 | c_bool_t tty = (isatty(fileno(stream)) && __C_debug_termattr); 84 | 85 | /* If we don't have flockfile() and funlockfile(), then we can't guarantee 86 | * exclusive access to the stream. A workaround for systems that do not have 87 | * these functions would be non-trivial, and probably not worth the effort. 88 | */ 89 | 90 | if(! format) 91 | return; 92 | 93 | l = strlen(format); 94 | if(l > 0) 95 | nl = (*(format + --l) == '\n'); 96 | 97 | #ifdef THREADED_LIBRARY 98 | #ifdef HAVE_FLOCKFILE 99 | flockfile(stderr); 100 | #endif /* HAVE_FLOCKFILE */ 101 | #endif /* THREADED_LIBRARY */ 102 | 103 | if(tty) 104 | { 105 | fprintf(stream, C_TERMATTR_BOLD); 106 | if(severity > C_DEBUG_INFO) 107 | fprintf(stream, C_TERMATTR_FG_RED); 108 | } 109 | 110 | if(__C_debug_trace) 111 | { 112 | #ifdef THREADED_LIBRARY 113 | fprintf(stream, "[%lX] ", (long)pthread_self()); 114 | #endif 115 | fprintf(stream, "%s(%d): ", file, line); 116 | } 117 | 118 | va_start(vp, format); 119 | vfprintf(stream, format, vp); 120 | va_end(vp); 121 | 122 | if(tty) 123 | { 124 | fputs(C_TERMATTR_FG_DEFAULT, stream); 125 | fputs(C_TERMATTR_NORMAL, stream); 126 | } 127 | 128 | if(! nl) 129 | fputc('\n', stream); 130 | 131 | fflush(stream); 132 | #ifdef THREADED_LIBRARY 133 | #ifdef HAVE_FLOCKFILE 134 | funlockfile(stderr); 135 | #endif /* HAVE_FLOCKFILE */ 136 | #endif /* THREADED_LIBRARY */ 137 | } 138 | 139 | /* 140 | */ 141 | 142 | c_bool_t C_debug_doassert(char *file, int line, char *expression) 143 | { 144 | C_debug_printf_x(file, line, C_DEBUG_ERROR, "Assertion failed: %s\n", 145 | expression); 146 | abort(); 147 | 148 | return(TRUE); 149 | } 150 | 151 | /* end of source file */ 152 | -------------------------------------------------------------------------------- /lib/dlobject.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | 31 | /* Local headers */ 32 | 33 | #include "cbase/defs.h" 34 | #include "cbase/system.h" 35 | #include "cbase/util.h" 36 | 37 | /* Functions */ 38 | 39 | c_dlobject_t *C_dlobject_create(const char *path) 40 | { 41 | c_dlobject_t *obj; 42 | 43 | if(! path) 44 | return(FALSE); 45 | 46 | if(! *path) 47 | return(FALSE); 48 | 49 | obj = C_new(c_dlobject_t); 50 | obj->path = C_string_dup(path); 51 | obj->loaded = FALSE; 52 | 53 | return(obj); 54 | } 55 | 56 | /* 57 | */ 58 | 59 | c_bool_t C_dlobject_load(c_dlobject_t *obj, c_bool_t lazy) 60 | { 61 | if(! obj) 62 | return(FALSE); 63 | 64 | obj->error = NULL; 65 | 66 | if(C_dlobject_isloaded(obj)) 67 | return(FALSE); 68 | 69 | if(! (obj->handle = dlopen(obj->path, (lazy ? RTLD_LAZY : RTLD_NOW)))) 70 | { 71 | obj->error = (char *)dlerror(); 72 | return(FALSE); 73 | } 74 | 75 | obj->loaded = TRUE; 76 | 77 | return(TRUE); 78 | } 79 | 80 | /* 81 | */ 82 | 83 | c_bool_t C_dlobject_unload(c_dlobject_t *obj) 84 | { 85 | if(! obj) 86 | return(FALSE); 87 | 88 | obj->error = NULL; 89 | 90 | if(! C_dlobject_isloaded(obj)) 91 | return(FALSE); 92 | 93 | if(dlclose(obj->handle) != 0) 94 | { 95 | obj->error = (char *)dlerror(); 96 | return(FALSE); 97 | } 98 | 99 | obj->loaded = FALSE; 100 | 101 | return(TRUE); 102 | } 103 | 104 | /* 105 | */ 106 | 107 | c_bool_t C_dlobject_destroy(c_dlobject_t *obj) 108 | { 109 | if(! obj) 110 | return(FALSE); 111 | 112 | if(C_dlobject_isloaded(obj)) 113 | return(FALSE); 114 | 115 | C_free(obj->path); 116 | C_free(obj); 117 | 118 | return(TRUE); 119 | } 120 | 121 | /* 122 | */ 123 | 124 | void *C_dlobject_lookup(c_dlobject_t *obj, const char *symbol) 125 | { 126 | void *p; 127 | 128 | if(! obj || ! symbol) 129 | return(FALSE); 130 | 131 | obj->error = NULL; 132 | 133 | if(! C_dlobject_isloaded(obj)) 134 | return(FALSE); 135 | 136 | if(! *symbol) 137 | return(FALSE); 138 | 139 | if(!(p = dlsym(obj->handle, symbol))) 140 | { 141 | obj->error = (char *)dlerror(); 142 | return(NULL); 143 | } 144 | 145 | return(p); 146 | } 147 | 148 | /* end of source file */ 149 | -------------------------------------------------------------------------------- /lib/dstring.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | 31 | /* Local headers */ 32 | 33 | #include "cbase/defs.h" 34 | #include "cbase/data.h" 35 | #include "cbase/system.h" 36 | 37 | /* Functions */ 38 | 39 | c_dstring_t *C_dstring_create(uint_t blocksz) 40 | { 41 | c_dstring_t *d; 42 | 43 | if(blocksz < C_DSTRING_MIN_BLOCKSZ) 44 | return(NULL); 45 | 46 | d = C_new(c_dstring_t); 47 | d->mem = C_newstr(blocksz); 48 | d->p = d->len = 0; 49 | d->blk = 1; 50 | d->blocksz = blocksz; 51 | 52 | return(d); 53 | } 54 | 55 | /* 56 | */ 57 | 58 | char *C_dstring_destroy(c_dstring_t *d) 59 | { 60 | char *r; 61 | 62 | if(!d) 63 | return(NULL); 64 | 65 | r = d->mem; 66 | *(r + d->len) = NUL; 67 | r = C_realloc(r, d->len + 1, char); 68 | C_free(d); 69 | 70 | return(r); 71 | } 72 | 73 | /* 74 | */ 75 | 76 | static char *__C_dstring_resize(c_dstring_t *d, off_t rlen) 77 | { 78 | uint_t r; 79 | 80 | if(!d) 81 | return(NULL); 82 | 83 | r = d->p; 84 | if(((d->p += rlen) >= (d->blocksz * d->blk)) || !rlen) 85 | { 86 | d->blk = (d->p / d->blocksz) + 1; 87 | d->mem = C_realloc(d->mem, d->blk * d->blocksz, char); 88 | } 89 | if(!rlen || d->p > d->len) 90 | d->len = d->p; 91 | 92 | return(rlen ? (char *)(d->mem + r) : NULL); 93 | } 94 | 95 | /* 96 | */ 97 | 98 | c_bool_t C_dstring_putc(c_dstring_t *d, char c) 99 | { 100 | char *r; 101 | 102 | if(!d || !c) 103 | return(FALSE); 104 | 105 | r = __C_dstring_resize(d, 1); 106 | *r = c; 107 | 108 | return(TRUE); 109 | } 110 | 111 | /* 112 | */ 113 | 114 | c_bool_t C_dstring_puts(c_dstring_t *d, const char *s) 115 | { 116 | return(C_dstring_puts_len(d, s, strlen(s))); 117 | } 118 | 119 | /* 120 | */ 121 | 122 | c_bool_t C_dstring_puts_len(c_dstring_t *d, const char *s, size_t len) 123 | { 124 | char *r; 125 | 126 | if(!d || !s) 127 | return(FALSE); 128 | if(!*s) 129 | return(FALSE); 130 | if(len <= 0) 131 | return(FALSE); 132 | 133 | r = __C_dstring_resize(d, (uint_t)len); 134 | memcpy((void *)r, (void *)s, len); 135 | 136 | return(TRUE); 137 | } 138 | 139 | /* 140 | */ 141 | 142 | char C_dstring_getc(c_dstring_t *d) 143 | { 144 | 145 | if(!d) 146 | return(NUL); 147 | if(d->p >= d->len) 148 | return(NUL); 149 | 150 | return(*(d->mem + d->p++)); 151 | } 152 | 153 | /* 154 | */ 155 | 156 | char *C_dstring_gets(c_dstring_t *d, char *s, size_t len, char termin) 157 | { 158 | char *p, *t = s; 159 | size_t l = len; 160 | uint_t i; 161 | 162 | if(!d || !s || !len) 163 | return(NULL); 164 | if(d->p == d->len) 165 | return(NULL); 166 | 167 | for(p = d->mem + d->p, i = d->len - d->p; 168 | i && l && (*p != termin); 169 | --i, --l) 170 | { 171 | *(t++) = *(p++); 172 | } 173 | *t = NUL; 174 | d->p = p - d->mem; 175 | 176 | return(s); 177 | } 178 | 179 | /* 180 | */ 181 | 182 | c_bool_t C_dstring_seek(c_dstring_t *d, off_t where, int whence) 183 | { 184 | off_t o; 185 | 186 | if(!d) 187 | return(FALSE); 188 | 189 | switch(whence) 190 | { 191 | case C_DSTRING_SEEK_REL: 192 | o = d->p + where; 193 | break; 194 | 195 | case C_DSTRING_SEEK_ABS: 196 | o = where; 197 | break; 198 | 199 | case C_DSTRING_SEEK_END: 200 | o = d->len - where; 201 | break; 202 | 203 | default: 204 | return(FALSE); 205 | } 206 | 207 | if(o < 0 || o > d->len) 208 | return(FALSE); 209 | d->p = o; 210 | 211 | return(TRUE); 212 | } 213 | 214 | /* 215 | */ 216 | 217 | c_bool_t C_dstring_trunc(c_dstring_t *d, off_t size) 218 | { 219 | 220 | if(!d) 221 | return(FALSE); 222 | if(size > d->len) 223 | return(FALSE); 224 | 225 | d->p = size; 226 | __C_dstring_resize(d, 0); 227 | 228 | return(TRUE); 229 | } 230 | 231 | /* 232 | */ 233 | 234 | c_dstring_t *C_dstring_load(const char *path, uint_t blocksz) 235 | { 236 | c_dstring_t *d; 237 | FILE *fp; 238 | struct stat st; 239 | uint_t i; 240 | char *p; 241 | size_t b; 242 | 243 | if(blocksz < C_DSTRING_MIN_BLOCKSZ || !path) 244 | return(NULL); 245 | if(!*path) 246 | return(NULL); 247 | if(stat(path, &st)) 248 | return(NULL); 249 | if(!(fp = fopen(path, "r"))) 250 | return(NULL); 251 | 252 | d = C_new(c_dstring_t); 253 | d->len = i = st.st_size; 254 | d->p = 0; 255 | d->blocksz = blocksz; 256 | d->blk = (d->len / d->blocksz) + 1; 257 | d->mem = p = C_newstr(d->blk * d->blocksz); 258 | while((b = fread(p, C_DSTRING_LOAD_BLOCKSZ, sizeof(char), fp)) 259 | == C_DSTRING_LOAD_BLOCKSZ) 260 | i -= C_DSTRING_LOAD_BLOCKSZ, p += C_DSTRING_LOAD_BLOCKSZ; 261 | fclose(fp); 262 | 263 | if(b != i) 264 | { 265 | C_free(d->mem); 266 | C_free(d); 267 | return(NULL); 268 | } 269 | 270 | return(d); 271 | } 272 | 273 | /* 274 | */ 275 | 276 | c_bool_t C_dstring_save(c_dstring_t *d, const char *path) 277 | { 278 | FILE *fp; 279 | uint_t i; 280 | char *p; 281 | size_t b; 282 | 283 | if(!d || !path) 284 | return(FALSE); 285 | if(!*path) 286 | return(FALSE); 287 | if(!(fp = fopen(path, "w"))) 288 | return(FALSE); 289 | 290 | i = d->len, p = d->mem; 291 | while((b = fwrite(p, C_DSTRING_LOAD_BLOCKSZ, sizeof(char), fp)) 292 | == C_DSTRING_LOAD_BLOCKSZ) 293 | i -= C_DSTRING_LOAD_BLOCKSZ, p += C_DSTRING_LOAD_BLOCKSZ; 294 | fclose(fp); 295 | 296 | return(b != i ? FALSE : TRUE); 297 | } 298 | 299 | /* end of source file */ 300 | -------------------------------------------------------------------------------- /lib/error.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #ifdef THREADED_LIBRARY 34 | #include 35 | #endif /* THREADED_LIBRARY */ 36 | 37 | /* Local headers */ 38 | 39 | #include "cbase/defs.h" 40 | #include "cbase/system.h" 41 | #include "cbase/cerrno.h" 42 | 43 | /* File scope variables */ 44 | 45 | static char *__C_error_progname = ""; 46 | 47 | #ifdef THREADED_LIBRARY 48 | 49 | static pthread_once_t __C_error_once = PTHREAD_ONCE_INIT; 50 | static pthread_key_t __C_error_key; 51 | 52 | #else /* THREADED_LIBRARY */ 53 | 54 | static int __c_errno = 0; /* global cbase error number */ 55 | 56 | #endif /* THREADED_LIBRARY */ 57 | 58 | static const int __C_error_nerr = 34; 59 | 60 | static const char *__C_error_errlist[] = 61 | { /* 0 */ "OK", 62 | /* 1 */ "invalid argument(s)", 63 | /* 2 */ "socket() call failed", 64 | /* 3 */ "call not valid in this state", 65 | /* 4 */ "unable to resolve network address", 66 | /* 5 */ "bind() call failed", 67 | /* 6 */ "operation would block", 68 | /* 7 */ "accept() call failed", 69 | /* 8 */ "wrong socket type for this operation", 70 | /* 9 */ "listen() call failed", 71 | /* 10 */ "unable to obtain socket info", 72 | /* 11 */ "fcntl() call failed", 73 | /* 12 */ "connection to peer lost", 74 | /* 13 */ "fdopen() call failed", 75 | /* 14 */ "connect() call failed", 76 | /* 15 */ "no connection available", 77 | /* 16 */ "send() call failed", 78 | /* 17 */ "recv() call failed", 79 | /* 18 */ "UDP message too big", 80 | /* 19 */ "sendto() call failed", 81 | /* 20 */ "recvfrom() call failed", 82 | /* 21 */ "connection or I/O timed out", 83 | /* 22 */ "unable to obtain service info", 84 | /* 23 */ "unable to fork", 85 | /* 24 */ "table full", 86 | /* 25 */ "select() call failed", 87 | /* 26 */ "ioctl() call failed", 88 | /* 27 */ "unable to get/set TTY attributes", 89 | /* 28 */ "descriptor does not refer to a TTY", 90 | /* 29 */ "getpty() call failed", 91 | /* 30 */ "open() call failed", 92 | /* 31 */ "general pseudoterminal error", 93 | /* 32 */ "execv() call failed", 94 | /* 33 */ "function/feature not implemented" 95 | }; 96 | 97 | /* Functions */ 98 | 99 | void C_error_init(const char *progname) 100 | { 101 | if(progname) 102 | __C_error_progname = (char *)progname; 103 | } 104 | 105 | /* 106 | */ 107 | 108 | void C_error_printf(const char *fmt, ...) 109 | { 110 | va_list vp; 111 | 112 | #ifdef THREADED_LIBRARY 113 | #ifdef HAVE_FLOCKFILE 114 | flockfile(stderr); 115 | #endif /* HAVE_FLOCKFILE */ 116 | #endif /* THREADED_LIBRARY */ 117 | 118 | fprintf(stderr, "%s: ", __C_error_progname); 119 | va_start(vp, fmt); 120 | vfprintf(stderr, fmt, vp); 121 | va_end(vp); 122 | fflush(stderr); 123 | 124 | #ifdef THREADED_LIBRARY 125 | #ifdef HAVE_FLOCKFILE 126 | funlockfile(stderr); 127 | #endif /* HAVE_FLOCKFILE */ 128 | #endif /* THREADED_LIBRARY */ 129 | } 130 | 131 | /* 132 | */ 133 | 134 | void C_error_usage(const char *usage) 135 | { 136 | 137 | fprintf(stderr, "%s: Usage: %s %s\n", __C_error_progname, 138 | __C_error_progname, usage); 139 | fflush(stderr); 140 | } 141 | 142 | /* 143 | */ 144 | 145 | void C_error_syserr(void) 146 | { 147 | 148 | #ifdef THREADED_LIBRARY 149 | #ifdef HAVE_FLOCKFILE 150 | flockfile(stderr); 151 | #endif /* HAVE_FLOCKFILE */ 152 | #endif /* THREADED_LIBRARY */ 153 | 154 | fprintf(stderr, "%s: %s\n", __C_error_progname, strerror(errno)); 155 | fflush(stderr); 156 | 157 | #ifdef THREADED_LIBRARY 158 | #ifdef HAVE_FLOCKFILE 159 | funlockfile(stderr); 160 | #endif /* HAVE_FLOCKFILE */ 161 | #endif /* THREADED_LIBRARY */ 162 | } 163 | 164 | /* 165 | */ 166 | 167 | const char *C_error_string(void) 168 | { 169 | if((c_errno < 0) || (c_errno >= __C_error_nerr)) 170 | return(NULL); 171 | 172 | return(__C_error_errlist[c_errno]); 173 | } 174 | 175 | /* 176 | */ 177 | 178 | #ifdef THREADED_LIBRARY 179 | 180 | static void __C_error_destructor(void *datum) 181 | { 182 | C_free(datum); 183 | } 184 | 185 | /* 186 | */ 187 | 188 | static void __C_error_init_once(void) 189 | { 190 | pthread_key_create(&__C_error_key, __C_error_destructor); 191 | } 192 | 193 | #endif /* THREADED_LIBRARY */ 194 | 195 | /* 196 | */ 197 | 198 | int C_error_get_errno(void) 199 | { 200 | #ifdef THREADED_LIBRARY 201 | 202 | int *e; 203 | 204 | pthread_once(&__C_error_once, __C_error_init_once); 205 | 206 | e = (int *)pthread_getspecific(__C_error_key); 207 | if(!e) 208 | { 209 | /* didn't exist, so create it */ 210 | 211 | e = C_new(int); 212 | *e = C_EOK; 213 | pthread_setspecific(__C_error_key, (void *)e); 214 | } 215 | 216 | return(*e); 217 | 218 | #else 219 | return(__c_errno); 220 | #endif /* THREADED_LIBRARY */ 221 | } 222 | 223 | /* 224 | */ 225 | 226 | void C_error_set_errno(int err) 227 | { 228 | #ifdef THREADED_LIBRARY 229 | int *e; 230 | 231 | pthread_once(&__C_error_once, __C_error_init_once); 232 | 233 | e = (int *)pthread_getspecific(__C_error_key); 234 | if(!e) 235 | { 236 | /* didn't exist, so create it */ 237 | 238 | e = C_new(int); 239 | pthread_setspecific(__C_error_key, (void *)e); 240 | } 241 | 242 | *e = err; 243 | 244 | #else /* THREADED_LIBRARY */ 245 | __c_errno = err; 246 | 247 | #endif /* THREADED_LIBRARY */ 248 | } 249 | 250 | /* end of source file */ 251 | -------------------------------------------------------------------------------- /lib/except.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | 31 | /* Local headers */ 32 | 33 | #include "cbase/except.h" 34 | #include "cbase/system.h" 35 | 36 | /* File scope variables */ 37 | 38 | static C_except_context_t *__C_top_context = NULL; 39 | 40 | /* External functions */ 41 | 42 | C_except_context_t *C_except_context_push(void) 43 | { 44 | C_except_context_t *context = C_new(C_except_context_t); 45 | context->prev = __C_top_context; 46 | __C_top_context = context; 47 | return __C_top_context; 48 | } 49 | 50 | /* 51 | */ 52 | 53 | C_except_context_t *C_except_context_top(int exception, 54 | const char *file, int line) 55 | { 56 | C_assert(__C_top_context != NULL); // assert if throw without try 57 | 58 | if(__C_top_context != NULL) 59 | { 60 | __C_top_context->exception = exception; 61 | __C_top_context->file = file; 62 | __C_top_context->line = line; 63 | } 64 | 65 | return __C_top_context; 66 | } 67 | 68 | /* 69 | */ 70 | 71 | int C_except_context_pop(void) 72 | { 73 | C_assert(__C_top_context != NULL); // assert if catch without try 74 | 75 | C_except_context_t *top = __C_top_context; 76 | int exception = 0; 77 | 78 | if(top) 79 | { 80 | exception = top->exception; 81 | __C_top_context = top->prev; 82 | C_free(top); 83 | } 84 | 85 | return(exception); 86 | } 87 | 88 | /* end of source file */ 89 | -------------------------------------------------------------------------------- /lib/exec.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* Feature test switches */ 28 | 29 | /* System headers */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /* Local headers */ 38 | 39 | #include "cbase/defs.h" 40 | #include "cbase/system.h" 41 | #include "cbase/util.h" 42 | 43 | /* Macros */ 44 | 45 | #define C_EXEC_NULLDEV "/dev/null" 46 | 47 | /* Functions */ 48 | 49 | int C_exec_run_cwd(char **argv, int fdin, int fdout, c_bool_t waitf, 50 | const char *cwd) 51 | { 52 | pid_t pid; 53 | int fdz = -1, r = 0, x; 54 | 55 | pid = fork(); 56 | switch(pid) 57 | { 58 | case -1: 59 | perror("fork"); 60 | exit(EXIT_FAILURE); 61 | 62 | case 0: /* child process */ 63 | if(fdin < 0 || fdout < 0) 64 | fdz = open(C_EXEC_NULLDEV, O_RDWR); 65 | dup2(((fdin < 0) ? fdz : fdin), STDIN_FILENO); 66 | dup2(((fdout < 0) ? fdz : fdout), STDOUT_FILENO); 67 | dup2(((fdout < 0) ? fdz : fdout), STDERR_FILENO); 68 | 69 | if(cwd) 70 | { 71 | x = chdir(cwd); 72 | if(x != 0) 73 | { 74 | perror("chdir"); 75 | exit(EXIT_FAILURE); 76 | } 77 | } 78 | 79 | execvp(*argv, argv); 80 | if(fdz >= 0) 81 | close(fdz); 82 | perror("execvp"); 83 | exit(EXIT_FAILURE); 84 | 85 | default: /* parent process */ 86 | if(waitf) 87 | r = C_exec_wait(pid); 88 | return(r); 89 | } 90 | } 91 | 92 | /* 93 | */ 94 | 95 | int C_exec_pipefrom_cwd(char **argv, int *fd, const char *cwd) 96 | { 97 | int pfd[2]; 98 | 99 | if(pipe(pfd)) 100 | { 101 | perror("pipe"); 102 | exit(EXIT_FAILURE); 103 | } 104 | *fd = pfd[0]; 105 | fcntl(pfd[0], F_SETFD, FD_CLOEXEC); 106 | 107 | return(C_exec_run_cwd(argv, -1, pfd[1], FALSE, cwd)); 108 | } 109 | 110 | /* 111 | */ 112 | 113 | int C_exec_pipeto_cwd(char **argv, int *fd, const char *cwd) 114 | { 115 | int pfd[2]; 116 | 117 | if(pipe(pfd)) 118 | { 119 | perror("pipe"); 120 | exit(EXIT_FAILURE); 121 | } 122 | *fd = pfd[1]; 123 | fcntl(pfd[1], F_SETFD, FD_CLOEXEC); 124 | 125 | return(C_exec_run_cwd(argv, pfd[0], -1, FALSE, cwd)); 126 | } 127 | 128 | /* 129 | */ 130 | 131 | int C_exec_wait(pid_t pid) 132 | { 133 | int st = 0; 134 | pid_t r; 135 | 136 | if(pid) 137 | { 138 | WAITPID: 139 | r = waitpid(pid, &st, 0); 140 | if((r < 0) && (errno == EINTR)) 141 | goto WAITPID; 142 | } 143 | else 144 | wait(&st); 145 | 146 | return(WEXITSTATUS(st)); 147 | } 148 | 149 | /* 150 | */ 151 | 152 | int C_exec_va_run_cwd(int fdin, int fdout, c_bool_t waitf, const char *cwd, 153 | ... /* , NULL */) 154 | { 155 | char **v; 156 | va_list vp; 157 | int r; 158 | 159 | va_start(vp, cwd); 160 | v = C_string_valist2vec(NULL, vp, NULL); 161 | va_end(vp); 162 | 163 | r = (v ? C_exec_run_cwd(v, fdin, fdout, waitf, cwd) : -1); 164 | if(v) 165 | C_free(v); 166 | 167 | return(r); 168 | } 169 | 170 | /* 171 | */ 172 | 173 | int C_exec_va_call(const char *arg, ... /* , NULL */) 174 | { 175 | char **v; 176 | va_list vp; 177 | int r; 178 | 179 | va_start(vp, arg); 180 | v = C_string_valist2vec(arg, vp, NULL); 181 | va_end(vp); 182 | 183 | r = (v ? C_exec_run(v, STDIN_FILENO, STDOUT_FILENO, TRUE) : -1); 184 | if(v) 185 | C_free(v); 186 | 187 | return(r); 188 | } 189 | 190 | /* end of source file */ 191 | -------------------------------------------------------------------------------- /lib/filedesc.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | /* Local headers */ 35 | 36 | #include "cbase/defs.h" 37 | #include "cbase/ipc.h" 38 | 39 | /* Macros */ 40 | 41 | /* Structures & Unions */ 42 | 43 | #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 44 | 45 | #ifdef HAVE_CONSTANT_CMSG_SPACE 46 | #define CBASE_CMSG_SPACE CMSG_SPACE 47 | #else 48 | #define CBASE_CMSG_SPACE(L) (sizeof(struct cmsghdr) + (L) + 16) 49 | #endif /* HAVE_CONSTANT_CMSG_SPACE */ 50 | 51 | union __c_cmsg_un 52 | { 53 | struct cmsghdr header; 54 | char control[CBASE_CMSG_SPACE(sizeof(int))]; 55 | }; 56 | #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 57 | 58 | /* Functions */ 59 | 60 | c_bool_t C_fd_send(int sd, int fd) 61 | { 62 | char *t = "x"; 63 | struct iovec vec; 64 | struct msghdr msg; 65 | 66 | #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 67 | struct cmsghdr *cmsg; 68 | union __c_cmsg_un control_un; 69 | 70 | msg.msg_control = control_un.control; 71 | msg.msg_controllen = sizeof(control_un.control); 72 | 73 | cmsg = CMSG_FIRSTHDR(&msg); 74 | cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 75 | cmsg->cmsg_level = SOL_SOCKET; 76 | cmsg->cmsg_type = SCM_RIGHTS; 77 | memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); 78 | #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 79 | 80 | #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS 81 | msg.msg_accrights = (caddr_t)&fd; 82 | msg.msg_accrightslen = sizeof(int); 83 | #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */ 84 | 85 | vec.iov_base = t; 86 | vec.iov_len = 1; 87 | msg.msg_iov = &vec; 88 | msg.msg_iovlen = 1; 89 | 90 | msg.msg_name = NULL; 91 | msg.msg_namelen = 0; 92 | 93 | return(sendmsg(sd, &msg, 0) != -1); 94 | } 95 | 96 | /* 97 | */ 98 | 99 | c_bool_t C_fd_recv(int sd, int *fd) 100 | { 101 | struct iovec vec; 102 | struct msghdr msg; 103 | ssize_t n; 104 | char t; 105 | #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS 106 | int nfd; 107 | #endif 108 | #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 109 | struct cmsghdr *cmsg; 110 | union __c_cmsg_un control_un; 111 | 112 | msg.msg_control = control_un.control; 113 | msg.msg_controllen = sizeof(control_un.control); 114 | #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 115 | 116 | #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS 117 | msg.msg_accrights = (caddr_t)&nfd; 118 | msg.msg_accrightslen = sizeof(int); 119 | #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */ 120 | 121 | vec.iov_base = &t; 122 | vec.iov_len = 1; 123 | msg.msg_iov = &vec; 124 | msg.msg_iovlen = 1; 125 | 126 | msg.msg_name = NULL; 127 | msg.msg_namelen = 0; 128 | 129 | if((n = recvmsg(sd, &msg, 0)) != 1) 130 | return(FALSE); /* error, or corrupt message? */ 131 | 132 | #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 133 | if(((cmsg = CMSG_FIRSTHDR(&msg)) != NULL) 134 | && (cmsg->cmsg_len == CMSG_LEN(sizeof(int)))) 135 | { 136 | if(cmsg->cmsg_level != SOL_SOCKET) 137 | return(FALSE); 138 | if(cmsg->cmsg_type != SCM_RIGHTS) 139 | return(FALSE); 140 | 141 | memcpy(fd, CMSG_DATA(cmsg), sizeof(int)); 142 | } 143 | else 144 | return(FALSE); /* descriptor was not passed */ 145 | #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 146 | 147 | #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS 148 | if(msg.msg_accrightslen != sizeof(int)) 149 | return(FALSE); /* descriptor was not passed */ 150 | 151 | *fd = nfd; 152 | #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */ 153 | 154 | return(TRUE); 155 | } 156 | 157 | /* end of source file */ 158 | -------------------------------------------------------------------------------- /lib/getXXbyYY_r.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2010 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_getXXbyYY_r_h 24 | #define __cbase_getXXbyYY_r_h 25 | 26 | #include "config.h" 27 | 28 | #include 29 | 30 | #ifdef HAVE_GETxxxxBYyyyy_R_POSIX 31 | 32 | #define C_gethostbyname_r gethostbyname_r 33 | #define C_gethostbyaddr_r gethostbyaddr_r 34 | #define C_getservbyname_r getservbyname_r 35 | #define C_getservbyport_r getservbyport_r 36 | 37 | #else /* ! HAVE_GETxxxxBYyyyy_R_POSIX */ 38 | 39 | extern int C_gethostbyname_r(const char *name, struct hostent *ret, 40 | char *buffer, int buflen, struct hostent **result, 41 | int *h_errnop); 42 | 43 | extern int C_gethostbyaddr_r(const char *addr, int length, int type, 44 | struct hostent *ret, char *buffer, int buflen, 45 | struct hostent **result, int *h_errnop); 46 | 47 | extern int C_getservbyname_r(const char *name, const char *proto, 48 | struct servent *ret, char *buffer, int buflen, 49 | struct servent **result); 50 | 51 | extern int C_getservbyport_r(int port, const char *proto, struct servent *ret, 52 | char *buffer, int buflen, 53 | struct servent **result); 54 | 55 | #endif /* HAVE_GETxxxxBYyyyy_R_POSIX */ 56 | 57 | #endif /* __cbase_getXXbyYY_r_h */ 58 | 59 | /* end of header file */ 60 | -------------------------------------------------------------------------------- /lib/hashtab.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | 31 | /* Local headers */ 32 | 33 | #include "cbase/defs.h" 34 | #include "cbase/data.h" 35 | #include "cbase/system.h" 36 | #include "cbase/util.h" 37 | 38 | /* File scope variables */ 39 | 40 | static uint_t (*__C_hashtable_hashfunc)(const char *s, uint_t modulo) 41 | = C_string_hash; 42 | 43 | /* Functions */ 44 | 45 | c_bool_t C_hashtable_set_hashfunc(uint_t (*func)(const char *s, uint_t modulo)) 46 | { 47 | c_bool_t r = FALSE; 48 | 49 | if(func) 50 | __C_hashtable_hashfunc = func, r = TRUE; 51 | 52 | return(r); 53 | } 54 | 55 | /* 56 | */ 57 | 58 | c_hashtable_t *C_hashtable_create(uint_t buckets) 59 | { 60 | c_hashtable_t *h; 61 | 62 | if(!buckets) 63 | return(NULL); 64 | 65 | h = C_new(c_hashtable_t); 66 | h->buckets = buckets; 67 | h->size = 0; 68 | h->table = C_calloc(buckets, c_linklist_t *); 69 | 70 | return(h); 71 | } 72 | 73 | /* 74 | */ 75 | 76 | void C_hashtable_destroy(c_hashtable_t *h) 77 | { 78 | uint_t i; 79 | c_linklist_t **p; 80 | c_tag_t *tag; 81 | 82 | if(!h) 83 | return; 84 | 85 | /* delete each linked list */ 86 | 87 | for(i = h->buckets, p = h->table; i--; ++p) 88 | { 89 | if(*p) 90 | { 91 | /* delete each tag (& its key) in the linked list */ 92 | 93 | for(C_linklist_move_head(*p); 94 | (tag = (c_tag_t *)C_linklist_restore(*p)) != NULL; 95 | C_linklist_move_next(*p)) 96 | { 97 | C_free(tag->key); 98 | 99 | if(h->destructor) 100 | h->destructor(tag->data); 101 | 102 | C_free(tag); 103 | } 104 | 105 | C_linklist_destroy(*p); 106 | } 107 | } 108 | 109 | /* delete the backbone and the container structure */ 110 | 111 | C_free(h->table); 112 | C_free(h); 113 | } 114 | 115 | /* 116 | */ 117 | 118 | c_bool_t C_hashtable_set_destructor(c_hashtable_t *h, 119 | void (*destructor)(void *data)) 120 | { 121 | if(!h) 122 | return(FALSE); 123 | 124 | h->destructor = destructor; 125 | 126 | return(TRUE); 127 | } 128 | 129 | /* 130 | */ 131 | 132 | c_bool_t C_hashtable_store(c_hashtable_t *h, const char *key, const void *data) 133 | { 134 | c_tag_t *tag; 135 | c_linklist_t **l; 136 | 137 | if(!h || !key || !data) 138 | return(FALSE); 139 | if(!*key) 140 | return(FALSE); 141 | 142 | tag = C_new(c_tag_t); 143 | tag->key = C_string_dup(key); 144 | tag->data = (char *)data; 145 | 146 | l = &(h->table[__C_hashtable_hashfunc(key, h->buckets)]); 147 | 148 | if(!(*l)) 149 | *l = C_linklist_create(); 150 | 151 | C_linklist_prepend(*l, (void *)tag); 152 | ++h->size; 153 | 154 | return(TRUE); 155 | } 156 | 157 | /* 158 | */ 159 | 160 | void *C_hashtable_restore(c_hashtable_t *h, const char *key) 161 | { 162 | c_tag_t *tag; 163 | c_linklist_t *l; 164 | 165 | if(!h || !key) 166 | return(FALSE); 167 | if(! *key) 168 | return(FALSE); 169 | 170 | if((l = h->table[__C_hashtable_hashfunc(key, h->buckets)])) 171 | { 172 | for(C_linklist_move_head(l); !C_linklist_isend(l); 173 | C_linklist_move_next(l)) 174 | { 175 | tag = (c_tag_t *)C_linklist_restore(l); 176 | if(!strcmp(tag->key, key)) 177 | return(tag->data); 178 | } 179 | } 180 | 181 | return(NULL); 182 | } 183 | 184 | /* 185 | */ 186 | 187 | c_bool_t C_hashtable_delete(c_hashtable_t *h, const char *key) 188 | { 189 | c_tag_t *tag; 190 | c_linklist_t *l; 191 | 192 | if(! *key) 193 | return(FALSE); 194 | 195 | if((l = h->table[__C_hashtable_hashfunc(key, h->buckets)])) 196 | { 197 | for(C_linklist_move_head(l); !C_linklist_isend(l); 198 | C_linklist_move_next(l)) 199 | { 200 | tag = (c_tag_t *)C_linklist_restore(l); 201 | if(!strcmp(tag->key, key)) 202 | { 203 | C_linklist_delete(l); 204 | --h->size; 205 | 206 | C_free(tag->key); 207 | 208 | if(h->destructor) 209 | h->destructor(tag->data); 210 | 211 | C_free(tag); 212 | 213 | return(TRUE); 214 | } 215 | } 216 | } 217 | 218 | return(FALSE); 219 | } 220 | 221 | /* 222 | */ 223 | 224 | char **C_hashtable_keys(c_hashtable_t *h, size_t *len) 225 | { 226 | c_vector_t *vec; 227 | c_linklist_t **p; 228 | c_tag_t *t; 229 | char **v; 230 | uint_t i; 231 | 232 | if(!h) 233 | return(NULL); 234 | 235 | vec = C_vector_start(h->buckets); 236 | 237 | for(i = h->buckets, p = h->table; i--; ++p) 238 | { 239 | for(C_linklist_move_head(*p); 240 | (t = (c_tag_t *)C_linklist_restore(*p)) != NULL; 241 | C_linklist_move_next(*p)) 242 | { 243 | C_vector_store(vec, C_string_dup(t->key)); 244 | } 245 | } 246 | 247 | v = C_vector_end(vec, len); 248 | 249 | return(v); 250 | } 251 | 252 | /* end of source file */ 253 | -------------------------------------------------------------------------------- /lib/hex.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | 31 | /* Local headers */ 32 | 33 | #include "cbase/defs.h" 34 | #include "cbase/util.h" 35 | 36 | /* Functions */ 37 | 38 | char C_hex_tonibble(int v) 39 | { 40 | 41 | if(v < 0 || v > 15) 42 | return(NUL); 43 | 44 | return(v + ((v < 10) ? '0' : ('A' - 10))); 45 | } 46 | 47 | /* 48 | */ 49 | 50 | int C_hex_fromnibble(char c) 51 | { 52 | 53 | if(!C_hex_isdigit(c)) 54 | return(-1); 55 | 56 | c = toupper(c); 57 | 58 | return(c - ((c < 'A') ? '0' : ('A' - 10))); 59 | } 60 | 61 | /* 62 | */ 63 | 64 | c_bool_t C_hex_tobyte(char *s, int v) 65 | { 66 | div_t d; 67 | 68 | if(v < 0 || v > 255 || !s) 69 | return(FALSE); 70 | 71 | d = div(v, 16); 72 | s[0] = C_hex_tonibble(d.quot); 73 | s[1] = C_hex_tonibble(d.rem); 74 | s[2] = NUL; 75 | 76 | return(TRUE); 77 | } 78 | 79 | /* 80 | */ 81 | 82 | int C_hex_frombyte(char * const s) 83 | { 84 | int hi, lo; 85 | 86 | if(!s) 87 | return(-1); 88 | if((hi = C_hex_fromnibble(s[0])) < 0) 89 | return(-1); 90 | if((lo = C_hex_fromnibble(s[1])) < 0) 91 | return(-1); 92 | 93 | return(16 * hi + lo); 94 | } 95 | 96 | /* 97 | */ 98 | 99 | c_bool_t C_hex_encode(char * const data, size_t len, char *s) 100 | { 101 | char *p, *q; 102 | int i; 103 | 104 | if(!data || !len || !s) 105 | return(FALSE); 106 | 107 | for(p = data, i = len, q = s; i--; ++p, q += 2) 108 | C_hex_tobyte(q, (int)*p); 109 | *q = NUL; 110 | 111 | return(TRUE); 112 | } 113 | 114 | /* 115 | */ 116 | 117 | c_bool_t C_hex_decode(char * const s, size_t len, char *data) 118 | { 119 | char *p, *q; 120 | int i; 121 | 122 | if(!s || !len || (len % 2) || !data) 123 | return(FALSE); 124 | 125 | for(q = s, i = len, p = data; i--; q += 2, ++p) 126 | *p = (char)C_hex_frombyte(q); 127 | 128 | return(TRUE); 129 | } 130 | 131 | /* end of source file */ 132 | 133 | -------------------------------------------------------------------------------- /lib/io.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | /* Local headers */ 34 | 35 | #include "cbase/defs.h" 36 | #include "cbase/system.h" 37 | 38 | /* Macros */ 39 | 40 | #define C_IO_BLOCKSZ 40 41 | 42 | /* Functions */ 43 | 44 | int C_io_getchar(uint_t delay) 45 | { 46 | struct termios t_old, t_new; 47 | int c; 48 | 49 | if(tcgetattr(STDIN_FILENO, &t_old)) 50 | return(-1); 51 | t_new = t_old; 52 | 53 | t_new.c_iflag &= ~(IXON | IXOFF); 54 | t_new.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN); 55 | t_new.c_cc[VMIN] = 0; 56 | t_new.c_cc[VTIME] = (delay * 10); 57 | 58 | if(tcsetattr(STDIN_FILENO, TCSANOW, &t_new)) 59 | return(-1); 60 | if((c = getchar()) == EOF) 61 | clearerr(stdin); 62 | 63 | tcsetattr(STDIN_FILENO, TCSANOW, &t_old); 64 | 65 | return(c); 66 | } 67 | 68 | /* 69 | */ 70 | 71 | int C_io_gets(FILE *fp, char *buf, size_t bufsz, char termin) 72 | { 73 | char *p = buf; 74 | int len = 0, ch; 75 | 76 | if(!buf || !bufsz) 77 | return(EOF); 78 | 79 | for(; (ch = fgetc(fp));) 80 | { 81 | if((ch == EOF) || (ch == termin)) 82 | break; 83 | *(p++) = ch; 84 | if(++len == bufsz) 85 | break; 86 | } 87 | 88 | *p = NUL; 89 | if(!len && ch == EOF) 90 | return(EOF); 91 | 92 | return(len); 93 | } 94 | 95 | /* 96 | */ 97 | 98 | int C_io_getpasswd(const char *prompt, char *buf, size_t bufsz) 99 | { 100 | struct termios t_old, t_new; 101 | int r; 102 | 103 | if(!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) 104 | return(-1); 105 | 106 | tcgetattr(STDIN_FILENO, &t_old); 107 | t_new = t_old; 108 | 109 | t_new.c_lflag &= ~ECHO; 110 | 111 | if(tcsetattr(STDIN_FILENO, TCSANOW, &t_new) < 0) 112 | return(-1); 113 | 114 | fputs(prompt, stdout); 115 | fflush(stdout); 116 | 117 | r = C_io_gets(stdin, buf, bufsz, '\n'); 118 | fputc('\n', stdout); 119 | 120 | if(tcsetattr(STDIN_FILENO, TCSANOW, &t_old) < 0) 121 | return(-1); 122 | 123 | return(r); 124 | } 125 | 126 | /* 127 | */ 128 | 129 | char *C_io_getline(FILE *fp, char termin, int *len) 130 | { 131 | int c = 0, blk = 1, ch, l = 0; 132 | char *s, *p; 133 | 134 | if(!fp) 135 | return(NULL); 136 | 137 | s = C_newstr(C_IO_BLOCKSZ); 138 | 139 | for(p = s; (ch = fgetc(fp));) 140 | { 141 | if((ch == EOF) || (ch == termin)) 142 | break; 143 | *p = (char)ch, l++; 144 | if(++c == C_IO_BLOCKSZ) 145 | { 146 | c = 0; 147 | s = C_realloc(s, (C_IO_BLOCKSZ * ++blk), char); 148 | p = s + ((blk - 1) * C_IO_BLOCKSZ); 149 | } 150 | else p++; 151 | } 152 | 153 | if(len) 154 | *len = l; 155 | 156 | if(!l && (ch == EOF)) 157 | { 158 | C_free(s); 159 | return(NULL); 160 | } 161 | 162 | *p = NUL; 163 | 164 | return(s = C_realloc(s, ++l, char)); 165 | } 166 | 167 | /* 168 | */ 169 | 170 | char *C_io_getline_buf(FILE *fp, char termin, c_buffer_t *buf) 171 | { 172 | int ch, l = 0; 173 | char *p; 174 | 175 | if(!fp || !buf) 176 | return(NULL); 177 | 178 | if(C_buffer_size(buf) < C_IO_BLOCKSZ) 179 | C_buffer_resize(buf, C_IO_BLOCKSZ); 180 | 181 | for(p = C_buffer_data(buf); (ch = fgetc(fp));) 182 | { 183 | if((ch == EOF) || (ch == termin)) 184 | break; 185 | 186 | *p = (char)ch; 187 | if(++l == C_buffer_size(buf)) 188 | { 189 | C_buffer_resize(buf, l + C_IO_BLOCKSZ); 190 | p = C_buffer_data(buf) + l; 191 | } 192 | else 193 | p++; 194 | } 195 | 196 | C_buffer_datalen(buf) = l; 197 | 198 | if(!l && (ch == EOF)) 199 | return(NULL); 200 | 201 | *p = NUL; 202 | 203 | return(C_buffer_data(buf)); 204 | } 205 | 206 | /* 207 | */ 208 | 209 | int C_io_fprintf(FILE *stream, const char *format, ...) 210 | { 211 | va_list vp; 212 | int r; 213 | 214 | #ifdef THREADED_LIBRARY 215 | #ifdef HAVE_FLOCKFILE 216 | flockfile(stream); 217 | #endif /* HAVE_FLOCKFILE */ 218 | #endif /* THREADED_LIBRARY */ 219 | va_start(vp, format); 220 | r = vfprintf(stream, format, vp); 221 | va_end(vp); 222 | 223 | #ifdef THREADED_LIBRARY 224 | #ifdef HAVE_FLOCKFILE 225 | funlockfile(stream); 226 | #endif /* HAVE_FLOCKFILE */ 227 | #endif /* THREADED_LIBRARY */ 228 | 229 | return(r); 230 | } 231 | 232 | /* end of source file */ 233 | -------------------------------------------------------------------------------- /lib/libcbase.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: cbase 7 | Description: C Foundation Library 8 | Version: @VERSION@ 9 | URL: http://www.hyperrealm.com/main.php?s=cbase 10 | Requires: 11 | Conflicts: 12 | Libs: -L${libdir} -lcbase 13 | Libs.private: @LIBS@ 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /lib/libcbase_mt.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: cbase 7 | Description: C Foundation Library 8 | Version: @VERSION@ 9 | URL: http://www.hyperrealm.com/main.php?s=cbase 10 | Requires: 11 | Conflicts: 12 | Libs: -L${libdir} -lcbase_mt 13 | Libs.private: @LIBS@ 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /lib/linklist.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* Local headers */ 28 | 29 | #include "cbase/defs.h" 30 | #include "cbase/data.h" 31 | #include "cbase/system.h" 32 | 33 | /* Functions */ 34 | 35 | static c_link_t *__C_linklist_unlink_r(c_linklist_t *l, c_link_t **p) 36 | { 37 | c_link_t *r; 38 | 39 | r = *p; 40 | if(l->head == r) 41 | l->head = r->next; 42 | if(l->tail == r) 43 | l->tail = r->prev; 44 | if((*p)->prev) 45 | (*p)->prev->next = (*p)->next; 46 | if((*p)->next) 47 | (*p)->next->prev = (*p)->prev; 48 | (*p) = (*p)->next; 49 | --l->size; 50 | 51 | return(r); 52 | } 53 | 54 | /* 55 | */ 56 | 57 | c_linklist_t *C_linklist_create(void) 58 | { 59 | c_linklist_t *l = C_new(c_linklist_t); 60 | 61 | l->head = l->tail = l->p = NULL; 62 | l->size = 0L; 63 | 64 | return(l); 65 | } 66 | 67 | /* 68 | */ 69 | 70 | void C_linklist_destroy(c_linklist_t *l) 71 | { 72 | c_link_t *p, *q; 73 | 74 | if(!l) 75 | return; 76 | 77 | for(p = l->head; p;) 78 | { 79 | q = p; 80 | p = p->next; 81 | 82 | if(l->destructor) 83 | l->destructor(q->data); 84 | 85 | C_free(q); 86 | } 87 | C_free(l); 88 | } 89 | 90 | /* 91 | */ 92 | 93 | c_bool_t C_linklist_set_destructor(c_linklist_t *l, 94 | void (*destructor)(void *data)) 95 | { 96 | if(!l) 97 | return(FALSE); 98 | 99 | l->destructor = destructor; 100 | return(TRUE); 101 | } 102 | 103 | /* 104 | */ 105 | 106 | c_bool_t C_linklist_store(c_linklist_t *l, const void *data) 107 | { 108 | if(!l) 109 | return(FALSE); 110 | 111 | return(C_linklist_store_r(l, data, &(l->p))); 112 | } 113 | 114 | /* 115 | */ 116 | 117 | c_bool_t C_linklist_store_r(c_linklist_t *l, const void *data, c_link_t **p) 118 | { 119 | c_link_t *q; 120 | 121 | if(!l || !data) 122 | return(FALSE); 123 | 124 | q = C_new(c_link_t); 125 | q->data = (void *)data; 126 | 127 | if(*p == l->head) /* new head? */ 128 | { 129 | q->next = l->head; 130 | q->prev = NULL; 131 | if(l->head) 132 | l->head->prev = q; 133 | l->head = q; 134 | if(!l->tail) 135 | l->tail = q; 136 | } 137 | else if(!(*p)) /* new tail? */ 138 | { 139 | q->next = NULL; 140 | q->prev = l->tail; 141 | if(l->tail) 142 | l->tail->next = q; 143 | l->tail = q; 144 | } 145 | else 146 | { 147 | q->next = *p; 148 | q->prev = (*p)->prev; 149 | if((*p)->prev) 150 | (*p)->prev->next = q; 151 | (*p)->prev = q; 152 | } 153 | *p = q; 154 | ++l->size; 155 | 156 | return(TRUE); 157 | } 158 | 159 | /* 160 | */ 161 | 162 | void *C_linklist_restore(c_linklist_t *l) 163 | { 164 | if(!l) 165 | return(NULL); 166 | 167 | return(C_linklist_restore_r(l, &(l->p))); 168 | } 169 | 170 | /* 171 | */ 172 | 173 | void *C_linklist_restore_r(c_linklist_t *l, c_link_t **p) 174 | { 175 | 176 | if(!l) 177 | return(NULL); 178 | 179 | return(*p ? (*p)->data : NULL); 180 | } 181 | 182 | /* 183 | */ 184 | 185 | c_bool_t C_linklist_search(c_linklist_t *l, const void *data) 186 | { 187 | if(!l) 188 | return(FALSE); 189 | 190 | return(C_linklist_search_r(l, data, &(l->p))); 191 | } 192 | 193 | /* 194 | */ 195 | 196 | c_bool_t C_linklist_search_r(c_linklist_t *l, const void *data, c_link_t **p) 197 | { 198 | void *d; 199 | 200 | for(C_linklist_move_head_r(l, p); 201 | (d = C_linklist_restore_r(l, p)) != NULL; 202 | C_linklist_move_next_r(l, p)) 203 | { 204 | if(d == data) 205 | return(TRUE); 206 | } 207 | 208 | return(FALSE); 209 | } 210 | 211 | /* 212 | */ 213 | 214 | c_bool_t C_linklist_prepend(c_linklist_t *l, const void *data) 215 | { 216 | c_link_t *p; 217 | 218 | if(!l || !data) 219 | return(FALSE); 220 | 221 | C_linklist_move_head_r(l, &p); 222 | return(C_linklist_store_r(l, data, &p)); 223 | } 224 | 225 | /* 226 | */ 227 | 228 | void *C_linklist_pop(c_linklist_t *l) 229 | { 230 | void *r; 231 | c_link_t *p, *q; 232 | 233 | if(!l) 234 | return(NULL); 235 | if(!l->size) 236 | return(NULL); 237 | 238 | C_linklist_move_head_r(l, &p); 239 | q = __C_linklist_unlink_r(l, &p); 240 | r = q->data; 241 | C_free(q); 242 | 243 | return(r); 244 | } 245 | 246 | /* 247 | */ 248 | 249 | void *C_linklist_peek(c_linklist_t *l) 250 | { 251 | c_link_t *p; 252 | 253 | if(!l) 254 | return(NULL); 255 | if(!l->size) 256 | return(NULL); 257 | 258 | C_linklist_move_head_r(l, &p); 259 | return(C_linklist_restore_r(l, &p)); 260 | } 261 | 262 | /* 263 | */ 264 | 265 | c_bool_t C_linklist_append(c_linklist_t *l, const void *data) 266 | { 267 | c_link_t *p; 268 | 269 | if(!l || !data) 270 | return(FALSE); 271 | 272 | C_linklist_move_end_r(l, &p); 273 | return(C_linklist_store_r(l, data, &p)); 274 | } 275 | 276 | /* 277 | */ 278 | 279 | c_bool_t C_linklist_delete(c_linklist_t *l) 280 | { 281 | if(!l) 282 | return(FALSE); 283 | if(!l->p) 284 | return(FALSE); 285 | 286 | return(C_linklist_delete_r(l, &(l->p))); 287 | } 288 | 289 | /* 290 | */ 291 | 292 | c_bool_t C_linklist_delete_r(c_linklist_t *l, c_link_t **p) 293 | { 294 | c_link_t *r; 295 | 296 | if(!l) 297 | return(FALSE); 298 | if(!*p) 299 | return(FALSE); 300 | 301 | r = __C_linklist_unlink_r(l, p); 302 | 303 | if(l->destructor) 304 | l->destructor(r->data); 305 | 306 | C_free(r); 307 | 308 | return(TRUE); 309 | } 310 | 311 | /* 312 | */ 313 | 314 | c_bool_t C_linklist_move(c_linklist_t *l, int where) 315 | { 316 | if(!l) 317 | return(FALSE); 318 | 319 | return(C_linklist_move_r(l, where, &(l->p))); 320 | } 321 | 322 | /* 323 | */ 324 | 325 | c_bool_t C_linklist_move_r(c_linklist_t *l, int where, c_link_t **p) 326 | { 327 | 328 | if(!l) 329 | return(FALSE); 330 | 331 | switch(where) 332 | { 333 | case C_LINKLIST_HEAD: 334 | *p = l->head; 335 | return(TRUE); 336 | 337 | case C_LINKLIST_TAIL: 338 | *p = l->tail; 339 | return(TRUE); 340 | 341 | case C_LINKLIST_NEXT: 342 | if(*p) 343 | { 344 | *p = (*p)->next; 345 | return(TRUE); 346 | } 347 | break; 348 | 349 | case C_LINKLIST_PREV: 350 | if(*p) 351 | if((*p)->prev) 352 | { 353 | *p = (*p)->prev; 354 | return(TRUE); 355 | } 356 | break; 357 | 358 | case C_LINKLIST_END: 359 | *p = NULL; 360 | return(TRUE); 361 | break; 362 | } 363 | 364 | return(FALSE); 365 | } 366 | 367 | /* end of source file */ 368 | -------------------------------------------------------------------------------- /lib/log.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #ifdef THREADED_LIBRARY 34 | #include 35 | #endif 36 | 37 | /* Local headers */ 38 | 39 | #include "cbase/defs.h" 40 | #include "cbase/system.h" 41 | 42 | /* File scope variables */ 43 | 44 | static FILE * __C_log_stream = NULL; 45 | 46 | static c_bool_t __C_log_console = TRUE, __C_log_termattr = TRUE; 47 | 48 | /* Functions */ 49 | 50 | void C_log_set_console(c_bool_t flag) 51 | { 52 | __C_log_console = flag; 53 | } 54 | 55 | /* 56 | */ 57 | 58 | void C_log_set_stream(FILE *stream) 59 | { 60 | if(stream != stderr) 61 | __C_log_stream = stream; 62 | } 63 | 64 | /* 65 | */ 66 | 67 | void C_log_message_x(int level, const char *format, ...) 68 | { 69 | char buf[32]; 70 | size_t l; 71 | c_bool_t nl = FALSE; 72 | c_bool_t tty = (isatty(fileno(stderr)) && __C_log_termattr); 73 | va_list vp; 74 | 75 | if(! format) 76 | return; 77 | 78 | l = strlen(format); 79 | if(l > 0) 80 | nl = (*(format + --l) == '\n'); 81 | 82 | C_time_format(0, buf, sizeof(buf), "[%x %X] "); 83 | 84 | /* log to console */ 85 | 86 | if(__C_log_console) 87 | { 88 | va_start(vp, format); 89 | 90 | fputs(buf, stderr); 91 | 92 | if(__C_log_termattr && tty) 93 | { 94 | fputs(C_TERMATTR_BOLD, stderr); 95 | 96 | switch(level) 97 | { 98 | case C_LOG_WARNING: 99 | fputs(C_TERMATTR_FG_MAGENTA, stderr); 100 | break; 101 | 102 | case C_LOG_ERROR: 103 | fputs(C_TERMATTR_FG_RED, stderr); 104 | break; 105 | 106 | case C_LOG_INFO: 107 | default: 108 | break; 109 | } 110 | } 111 | 112 | vfprintf(stderr, format, vp); 113 | if(! nl) 114 | fputc('\n', stderr); 115 | 116 | if(__C_log_termattr && tty) 117 | { 118 | fputs(C_TERMATTR_FG_DEFAULT, stderr); 119 | fputs(C_TERMATTR_NORMAL, stderr); 120 | } 121 | 122 | fflush(stderr); 123 | 124 | va_end(vp); 125 | } 126 | 127 | /* log to file */ 128 | 129 | if(__C_log_stream) 130 | { 131 | va_start(vp, format); 132 | 133 | fputs(buf, __C_log_stream); 134 | vfprintf(__C_log_stream, format, vp); 135 | if(! nl) 136 | fputc('\n', __C_log_stream); 137 | 138 | fflush(__C_log_stream); 139 | 140 | va_end(vp); 141 | } 142 | } 143 | 144 | /* 145 | */ 146 | 147 | void C_log_set_termattr(c_bool_t flag) 148 | { 149 | __C_log_termattr = flag; 150 | } 151 | 152 | /* end of source file */ 153 | -------------------------------------------------------------------------------- /lib/memfile.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | /* Local headers */ 35 | 36 | #include "cbase/defs.h" 37 | #include "cbase/system.h" 38 | #include "cbase/ipc.h" 39 | 40 | /* File scope functions */ 41 | 42 | static off_t __C_memfile_round_size(off_t size) 43 | { 44 | #if defined _SC_PAGESIZE 45 | long pagesize = sysconf(_SC_PAGESIZE); 46 | #elif defined HAVE_GETPAGESIZE 47 | long pagesize = getpagesize(); 48 | #else 49 | #error "No means to determine system page size." 50 | #endif 51 | 52 | return((off_t)(size + pagesize - (size % pagesize))); 53 | } 54 | 55 | /* Functions */ 56 | 57 | c_memfile_t *C_memfile_open(const char *file, c_bool_t readonly) 58 | { 59 | c_memfile_t *f; 60 | struct stat stbuf; 61 | 62 | if(!file) 63 | return(NULL); 64 | 65 | if(stat(file, &stbuf)) 66 | return(NULL); 67 | 68 | f = C_new(c_memfile_t); 69 | if((f->fd = open(file, O_RDWR)) < 0) 70 | return(C_free(f)); 71 | 72 | f->length = stbuf.st_size; 73 | f->base = mmap(NULL, f->length, 74 | (readonly ? PROT_READ : (PROT_READ | PROT_WRITE)), MAP_SHARED, 75 | f->fd, 0); 76 | 77 | if(f->base == MAP_FAILED) 78 | { 79 | close(f->fd); 80 | return(C_free(f)); 81 | } 82 | 83 | return(f); 84 | } 85 | 86 | /* 87 | */ 88 | 89 | c_bool_t C_memfile_close(c_memfile_t *mf) 90 | { 91 | if(!mf) 92 | return(FALSE); 93 | 94 | if(msync(mf->base, mf->length, MS_SYNC)) 95 | return(FALSE); 96 | 97 | if(munmap(mf->base, mf->length)) 98 | return(FALSE); 99 | 100 | if(close(mf->fd)) 101 | return(FALSE); 102 | 103 | C_free(mf); 104 | 105 | return(TRUE); 106 | } 107 | 108 | /* 109 | */ 110 | 111 | c_bool_t C_memfile_resize(c_memfile_t *mf, off_t length) 112 | { 113 | off_t newsize; 114 | 115 | if(!mf || (length < 0)) 116 | return(FALSE); 117 | 118 | newsize = __C_memfile_round_size(length); 119 | 120 | if(ftruncate(mf->fd, newsize)) 121 | return(FALSE); 122 | 123 | if(newsize > mf->length) 124 | memset(mf->base + mf->length, 0, (newsize - mf->length)); 125 | 126 | mf->length = newsize; 127 | 128 | return(TRUE); 129 | } 130 | 131 | /* 132 | */ 133 | 134 | c_bool_t C_memfile_sync(c_memfile_t *mf, c_bool_t async) 135 | { 136 | if(!mf) 137 | return(FALSE); 138 | 139 | return(! msync(mf->base, mf->length, (async ? MS_ASYNC : MS_SYNC))); 140 | } 141 | 142 | /* end of source file */ 143 | -------------------------------------------------------------------------------- /lib/memory.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | 32 | /* Local headers */ 33 | 34 | #include "cbase/defs.h" 35 | #include "cbase/system.h" 36 | #include "cbase/util.h" 37 | 38 | /* File scope variables */ 39 | 40 | static c_bool_t (*__C_mem_errfunc)(void) = NULL; 41 | 42 | static void (*__C_mem_alloc_hook)(const void *, const void *, size_t) = NULL; 43 | 44 | /* Functions */ 45 | 46 | void C_mem_default_alloc_hook(const void *p_old, const void *p_new, size_t len) 47 | { 48 | C_debug_printf("default alloc hook\n"); 49 | 50 | if(p_old && ! p_new && ! len) 51 | C_log_info("MEMORY: Free @ %p", p_old); 52 | else if(p_new && ! p_old) 53 | C_log_info("MEMORY: Alloc %7d bytes @ %p", len, p_new); 54 | else if(p_old && p_new) 55 | C_log_info("MEMORY: Realloc %7d bytes @ %p from %p", len, p_new, 56 | p_old); 57 | } 58 | 59 | /* 60 | */ 61 | 62 | void *C_mem_manage(void *p, size_t n, c_bool_t clearf) 63 | { 64 | void *r = NULL; 65 | 66 | for(;;) 67 | { 68 | if((r = realloc(p, n))) 69 | { 70 | #pragma GCC diagnostic push 71 | #pragma GCC diagnostic ignored "-Wuse-after-free" 72 | 73 | if(__C_mem_alloc_hook) 74 | __C_mem_alloc_hook(p, r, n); 75 | 76 | #pragma GCC diagnostic pop 77 | 78 | if(clearf) 79 | memset(r, 0, n); 80 | 81 | break; 82 | } 83 | else 84 | { 85 | if(__C_mem_errfunc) 86 | { 87 | if(! __C_mem_errfunc()) 88 | break; 89 | } 90 | else 91 | break; 92 | } 93 | } 94 | 95 | return(r); 96 | } 97 | 98 | /* 99 | */ 100 | 101 | void C_mem_set_errorfunc(c_bool_t (*func)(void)) 102 | { 103 | 104 | __C_mem_errfunc = func; 105 | } 106 | 107 | /* 108 | */ 109 | 110 | void C_mem_set_alloc_hook(void (*func)(const void *p_old, const void *p_new, 111 | size_t len)) 112 | { 113 | 114 | __C_mem_alloc_hook = func; 115 | } 116 | 117 | /* 118 | */ 119 | 120 | void *C_mem_free(void *p) 121 | { 122 | 123 | if(p) 124 | free(p); 125 | 126 | if(__C_mem_alloc_hook) 127 | __C_mem_alloc_hook(p, NULL, 0); 128 | 129 | return(NULL); 130 | } 131 | 132 | /* 133 | */ 134 | 135 | void C_mem_free_vec(char **v) 136 | { 137 | char **p; 138 | 139 | if(!v) 140 | return; 141 | 142 | for(p = v; *p; ++p) 143 | C_free(*p); 144 | C_free(v); 145 | } 146 | 147 | /* 148 | */ 149 | 150 | uint_t C_mem_va_free(uint_t n, ...) 151 | { 152 | int i, r = 0; 153 | va_list vp; 154 | void *p; 155 | 156 | va_start(vp, n); 157 | 158 | for(i = n; i--;) 159 | if((p = va_arg(vp, void *))) 160 | C_free(p), ++r; 161 | 162 | va_end(vp); 163 | return(r); 164 | } 165 | 166 | /* 167 | */ 168 | 169 | size_t C_mem_defrag(void *p, size_t elemsz, size_t len, 170 | c_bool_t (*isempty)(void *elem)) 171 | { 172 | uint_t mlen = 0, hlen = 0, i = 0; 173 | void *h = NULL, *m = NULL, *q; 174 | 175 | for(q = p; i < len; ++i, q += elemsz) 176 | { 177 | if(isempty(q)) 178 | { 179 | if(mlen) 180 | { 181 | memmove(h, m, (size_t)(mlen * elemsz)); 182 | h += (mlen * elemsz); 183 | mlen = 0; 184 | } 185 | if(!(hlen++)) 186 | h = q; 187 | } 188 | else 189 | { 190 | if(!hlen) 191 | continue; 192 | else if(!(mlen++)) 193 | m = q; 194 | } 195 | } 196 | 197 | return((size_t)(len - hlen)); 198 | } 199 | 200 | /* 201 | */ 202 | 203 | c_buffer_t *C_buffer_create(size_t bufsz) 204 | { 205 | c_buffer_t *buf = C_new(c_buffer_t); 206 | 207 | buf->bufsz = bufsz; 208 | buf->buf = C_newb(bufsz); 209 | return(buf); 210 | } 211 | 212 | /* 213 | */ 214 | 215 | c_buffer_t *C_buffer_resize(c_buffer_t *buf, size_t newsz) 216 | { 217 | 218 | if(newsz <= 0) 219 | return(NULL); 220 | 221 | buf->buf = C_realloc(buf->buf, newsz, char); 222 | buf->bufsz = newsz; 223 | 224 | return(buf); 225 | } 226 | 227 | /* 228 | */ 229 | 230 | void C_buffer_clear(c_buffer_t *buf) 231 | { 232 | 233 | if(! buf) 234 | return; 235 | 236 | buf->datalen = 0; 237 | memset((void *)buf->buf, 0, buf->bufsz); 238 | } 239 | 240 | /* 241 | */ 242 | 243 | void C_buffer_destroy(c_buffer_t *buf) 244 | { 245 | 246 | if(!buf) 247 | return; 248 | 249 | C_free(buf->buf); 250 | C_free(buf); 251 | } 252 | 253 | /* end of source file */ 254 | -------------------------------------------------------------------------------- /lib/mempool.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | 30 | /* Local headers */ 31 | 32 | #include "cbase/defs.h" 33 | #include "cbase/system.h" 34 | 35 | /* Functions */ 36 | 37 | c_mempool_t *C_mempool_create(size_t size) 38 | { 39 | c_mempool_t *pool = C_new(c_mempool_t); 40 | 41 | pool->size = size; 42 | pool->base = (void *)C_newb(size); 43 | if(! pool->base) 44 | { 45 | C_free(pool); 46 | return(NULL); 47 | } 48 | 49 | pool->pos = 0; 50 | 51 | return(pool); 52 | } 53 | 54 | /* 55 | */ 56 | 57 | void C_mempool_destroy(c_mempool_t *pool) 58 | { 59 | if(! pool) 60 | return; 61 | 62 | C_free(pool->base); 63 | C_free(pool); 64 | } 65 | 66 | /* 67 | */ 68 | 69 | void *C_mempool_alloc(c_mempool_t *pool, size_t size) 70 | { 71 | void *p; 72 | size_t rsz; 73 | int r; 74 | 75 | if(!pool || (size < 1)) 76 | return(NULL); 77 | 78 | p = pool->base + pool->pos; 79 | rsz = size; 80 | r = (size % sizeof(void *)); 81 | if(r != 0) 82 | rsz += (sizeof(void *) - r); 83 | 84 | if(C_mempool_avail(pool) < rsz) 85 | return(NULL); 86 | 87 | pool->pos += rsz; 88 | 89 | return(p); 90 | } 91 | 92 | /* 93 | */ 94 | 95 | size_t C_mempool_avail(c_mempool_t *pool) 96 | { 97 | if(! pool) 98 | return(0); 99 | 100 | return(pool->size - pool->pos); 101 | } 102 | 103 | /* end of source file */ 104 | -------------------------------------------------------------------------------- /lib/netcommon.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef __cbase_netcommon_h 24 | #define __cbase_netcommon_h 25 | 26 | #include "config.h" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "cbase/util.h" 37 | 38 | #ifndef HAVE_TYPE_IN_ADDR_T 39 | typedef uint32_t in_addr_t; 40 | #endif 41 | 42 | #ifndef HAVE_TYPE_IN_PORT_T 43 | typedef uint16_t in_port_t; 44 | #endif 45 | 46 | #ifndef HAVE_TYPE_SOCKLEN_T 47 | typedef size_t socklen_t; 48 | #endif 49 | 50 | #ifndef INADDR_NONE 51 | #define INADDR_NONE -1 52 | #endif 53 | 54 | #define C_NET_BUFSZ 8192 55 | 56 | #define C_NET_CREATED 0 57 | #define C_NET_LISTENING 1 58 | #define C_NET_ACCEPTING 2 59 | #define C_NET_CONNECTED 3 60 | #define C_NET_SHUTDOWN 4 61 | 62 | #define C_NET_NTYPES 3 63 | 64 | extern const int __C_net_socktypes[C_NET_NTYPES]; 65 | extern const char *__C_net_protocols[C_NET_NTYPES]; 66 | 67 | extern c_bool_t __C_socket_addr2sock(struct sockaddr_in *sa, const char *addr); 68 | extern c_bool_t __C_socket_sock2addr(struct sockaddr_in *sa, char *addr, 69 | size_t addrsz); 70 | 71 | extern c_buffer_t *__C_net_get_buffer(void); 72 | 73 | #endif /* __cbase_netcommon_h */ 74 | 75 | /* end of common header */ 76 | -------------------------------------------------------------------------------- /lib/netinfo.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #ifdef THREADED_LIBRARY 31 | #include 32 | #endif /* THREADED_LIBRARY */ 33 | 34 | /* Local headers */ 35 | 36 | #include "netcommon.h" 37 | #include "cbase/defs.h" 38 | #include "cbase/net.h" 39 | #include "cbase/cerrno.h" 40 | #include "cbase/system.h" 41 | #include "getXXbyYY_r.h" 42 | 43 | /* File scope variables */ 44 | 45 | #ifdef THREADED_LIBRARY 46 | 47 | static pthread_once_t __C_net_once = PTHREAD_ONCE_INIT; 48 | static pthread_key_t __C_net_key; 49 | 50 | /* File scope functions */ 51 | 52 | static void __C_net_destructor(void *arg) 53 | { 54 | C_buffer_destroy((c_buffer_t *)arg); 55 | } 56 | 57 | /* 58 | */ 59 | 60 | static void __C_net_init_once(void) 61 | { 62 | pthread_key_create(&__C_net_key, __C_net_destructor); 63 | } 64 | 65 | #endif /* THREADED_LIBRARY */ 66 | 67 | /* External functions */ 68 | 69 | #ifdef THREADED_LIBRARY 70 | 71 | c_buffer_t *__C_net_get_buffer(void) 72 | { 73 | c_buffer_t *buf = NULL; 74 | 75 | pthread_once(&__C_net_once, __C_net_init_once); 76 | 77 | buf = (c_buffer_t *)pthread_getspecific(__C_net_key); 78 | if(!buf) 79 | { 80 | /* didn't exist, so create it */ 81 | 82 | buf = C_buffer_create(C_NET_BUFSZ); 83 | pthread_setspecific(__C_net_key, (void *)buf); 84 | } 85 | 86 | return(buf); 87 | } 88 | 89 | #else 90 | 91 | c_buffer_t *__C_net_get_buffer(void) 92 | { 93 | static c_buffer_t *buf = NULL; 94 | 95 | if(!buf) 96 | buf = C_buffer_create(C_NET_BUFSZ); 97 | 98 | return(buf); 99 | } 100 | 101 | #endif /* THREADED_LIBRARY */ 102 | 103 | /* 104 | */ 105 | 106 | in_port_t C_net_get_svcport(const char *name, uint_t *type) 107 | { 108 | struct servent se, *rse; 109 | int i, r; 110 | c_buffer_t *rbuf = __C_net_get_buffer(); 111 | 112 | if(!name || !type) 113 | { 114 | C_error_set_errno(C_EINVAL); 115 | return(-1); 116 | } 117 | if(!*name || (*type > C_NET_MAXTYPE)) 118 | { 119 | C_error_set_errno(C_EINVAL); 120 | return(-1); 121 | } 122 | 123 | GETSERVBYNAME: 124 | if(C_getservbyname_r(name, __C_net_protocols[*type], &se, rbuf->buf, 125 | rbuf->bufsz, &rse) < 0) 126 | { 127 | if(errno == ERANGE) 128 | { 129 | C_buffer_resize(rbuf, rbuf->bufsz + C_NET_BUFSZ); 130 | goto GETSERVBYNAME; 131 | } 132 | else 133 | { 134 | C_error_set_errno(C_ESVCINFO); 135 | return(-1); 136 | } 137 | } 138 | 139 | if(*type == C_NET_UNKNOWN) 140 | for(i = 0; i < C_NET_MAXTYPE - 1; i++) 141 | if(!strcmp(se.s_proto, __C_net_protocols[i])) 142 | { 143 | *type = i; 144 | break; 145 | } 146 | 147 | r = (int)ntohl(se.s_port); 148 | 149 | return((in_port_t)r); 150 | } 151 | 152 | /* 153 | */ 154 | 155 | c_bool_t C_net_get_svcname(in_port_t port, uint_t *type, char *buf, 156 | size_t bufsz) 157 | { 158 | struct servent se, *rse; 159 | int i; 160 | c_buffer_t *rbuf = __C_net_get_buffer(); 161 | 162 | if(!type || !buf || !bufsz) 163 | { 164 | C_error_set_errno(C_EINVAL); 165 | return(FALSE); 166 | } 167 | 168 | if(*type > C_NET_MAXTYPE) 169 | { 170 | C_error_set_errno(C_EINVAL); 171 | return(FALSE); 172 | } 173 | 174 | GETSERVBYPORT: 175 | if(C_getservbyport_r((int)port, __C_net_protocols[*type], &se, rbuf->buf, 176 | rbuf->bufsz, &rse) < 0) 177 | { 178 | if(errno == ERANGE) 179 | { 180 | C_buffer_resize(rbuf, rbuf->bufsz + C_NET_BUFSZ); 181 | goto GETSERVBYPORT; 182 | } 183 | else 184 | { 185 | C_error_set_errno(C_ESVCINFO); 186 | return(FALSE); 187 | } 188 | } 189 | 190 | if(*type == C_NET_UNKNOWN) 191 | for(i = 0; i < C_NET_MAXTYPE - 1; i++) 192 | if(!strcmp(se.s_proto, __C_net_protocols[i])) 193 | { 194 | *type = i; 195 | break; 196 | } 197 | 198 | strncpy(buf, se.s_name, --bufsz); 199 | *(buf + bufsz) = NUL; 200 | return(TRUE); 201 | } 202 | 203 | /* 204 | */ 205 | 206 | c_bool_t C_net_resolve(const char *ipaddr, char *buf, size_t bufsz) 207 | { 208 | in_addr_t addr; 209 | struct hostent he, *rhe; 210 | c_buffer_t *rbuf = __C_net_get_buffer(); 211 | int herr; 212 | 213 | if(!ipaddr || !buf || !bufsz) 214 | { 215 | C_error_set_errno(C_EINVAL); 216 | return(FALSE); 217 | } 218 | if(!*ipaddr) 219 | { 220 | C_error_set_errno(C_EINVAL); 221 | return(FALSE); 222 | } 223 | 224 | if((addr = inet_addr(ipaddr)) == -1) 225 | { 226 | C_error_set_errno(C_EADDRINFO); 227 | return(FALSE); 228 | } 229 | 230 | GETHOSTBYADDR: 231 | if(C_gethostbyaddr_r((char *)&addr, sizeof(in_addr_t), AF_INET, &he, 232 | rbuf->buf, rbuf->bufsz, &rhe, &herr) < 0) 233 | { 234 | if(herr == ERANGE) 235 | { 236 | C_buffer_resize(rbuf, rbuf->bufsz + C_NET_BUFSZ); 237 | goto GETHOSTBYADDR; 238 | } 239 | else 240 | { 241 | C_error_set_errno(C_EADDRINFO); 242 | return(FALSE); 243 | } 244 | } 245 | 246 | strncpy(buf, he.h_name, --bufsz); 247 | *(buf + bufsz) = NUL; 248 | return(TRUE); 249 | } 250 | 251 | /* 252 | */ 253 | 254 | c_bool_t C_net_resolve_local(char *addr, char *ipaddr, size_t bufsz, 255 | in_addr_t *ip) 256 | { 257 | struct hostent he, *rhe; 258 | struct in_addr in; 259 | char *p; 260 | c_buffer_t *rbuf = __C_net_get_buffer(); 261 | int herr; 262 | 263 | if((!addr && !ipaddr && !ip) || (bufsz == 0)) 264 | { 265 | C_error_set_errno(C_EINVAL); 266 | return(FALSE); 267 | } 268 | 269 | if(!(p = C_system_get_hostname())) 270 | { 271 | C_error_set_errno(C_EADDRINFO); 272 | return(FALSE); 273 | } 274 | 275 | GETHOSTBYNAME: 276 | if(C_gethostbyname_r(p, &he, rbuf->buf, rbuf->bufsz, &rhe, &herr) < 0) 277 | { 278 | if(herr == ERANGE) 279 | { 280 | C_buffer_resize(rbuf, rbuf->bufsz + C_NET_BUFSZ); 281 | goto GETHOSTBYNAME; 282 | } 283 | else 284 | { 285 | C_error_set_errno(C_EADDRINFO); 286 | return(FALSE); 287 | } 288 | } 289 | 290 | if(addr) 291 | { 292 | strncpy(addr, he.h_name, --bufsz); 293 | *(addr + bufsz) = NUL; 294 | } 295 | 296 | memcpy((void *)&(in.s_addr), (void *)*(he.h_addr_list), sizeof(in.s_addr)); 297 | 298 | if(ipaddr) 299 | { 300 | strncpy(ipaddr, inet_ntoa(in), bufsz); 301 | *(ipaddr + bufsz) = NUL; 302 | } 303 | 304 | if(ip) 305 | *ip = ntohl(in.s_addr); 306 | 307 | return(TRUE); 308 | } 309 | 310 | /* end of source file */ 311 | -------------------------------------------------------------------------------- /lib/pty.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | #define _XOPEN_SOURCE 500 28 | 29 | /* System headers */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #if defined HAVE_STROPTS_H 37 | #include 38 | #elif defined HAVE_OPENPTY 39 | #include 40 | #else 41 | #include 42 | #endif 43 | #include 44 | #include 45 | 46 | /* Local headers */ 47 | 48 | #include "cbase/defs.h" 49 | #include "cbase/ipc.h" 50 | #include "cbase/system.h" 51 | #include "cbase/cerrno.h" 52 | 53 | /* Macros */ 54 | 55 | #ifdef HAVE_STROPTS_H 56 | #define C_TERM_MASTER "/dev/ptmx" 57 | #endif 58 | 59 | /* Functions */ 60 | 61 | #if !(defined HAVE_STROPTS_H || defined HAVE_OPENPTY) 62 | static int __C_pty_open_master_BSD(char *pts_name); 63 | static int __C_pty_open_slave_BSD(int fdm, char *pts_name); 64 | #endif 65 | 66 | /* 67 | */ 68 | 69 | c_pty_t *C_pty_create(void) 70 | { 71 | int mfd, sfd; 72 | c_pty_t *pty; 73 | char pts_name[11] = ""; 74 | 75 | #if defined HAVE_STROPTS_H 76 | 77 | char *pts = NULL; 78 | c_bool_t ok = FALSE; 79 | 80 | /* open master */ 81 | 82 | if((mfd = open(C_TERM_MASTER, O_RDWR)) >= 0) 83 | if(grantpt(mfd) >= 0) 84 | if(unlockpt(mfd) >= 0) 85 | ok = TRUE; 86 | 87 | if(! ok) 88 | { 89 | C_error_set_errno(C_EGETPTY); 90 | return(NULL); 91 | } 92 | 93 | /* open slave */ 94 | 95 | pts = (char *)ptsname(mfd); 96 | if(pts == NULL) 97 | { 98 | C_error_set_errno(C_EGETPTY); 99 | return(NULL); 100 | } 101 | 102 | if((sfd = open(pts, O_RDWR)) < 0) 103 | { 104 | C_error_set_errno(C_EOPEN); 105 | return(NULL); 106 | } 107 | 108 | ok = FALSE; 109 | 110 | if(ioctl(sfd, I_PUSH, "ptem") >= 0) 111 | if(ioctl(sfd, I_PUSH, "ldterm") >= 0) 112 | ok = TRUE; 113 | 114 | if(! ok) 115 | { 116 | C_error_set_errno(C_EIOCTL); 117 | return(NULL); 118 | } 119 | 120 | #elif defined HAVE_OPENPTY 121 | 122 | if(openpty(&mfd, &sfd, pts_name, NULL, NULL) < 0) 123 | { 124 | C_error_set_errno(C_EGETPTY); 125 | return(NULL); 126 | } 127 | 128 | #else /* fall back on the old crude BSD way */ 129 | 130 | if((mfd = __C_pty_open_master_BSD(pts_name)) < 0) 131 | { 132 | C_error_set_errno(C_EOPEN); 133 | return(NULL); 134 | } 135 | 136 | if((sfd = __C_pty_open_slave_BSD(mfd, pts_name)) < 0) 137 | { 138 | C_error_set_errno(C_EOPEN); 139 | return(NULL); 140 | } 141 | 142 | #endif 143 | 144 | pty = C_new(c_pty_t); 145 | pty->master_fd = mfd; 146 | pty->slave_fd = sfd; 147 | strcpy(pty->pts_name, pts_name); 148 | 149 | return(pty); 150 | } 151 | 152 | /* 153 | */ 154 | 155 | c_bool_t C_pty_destroy(c_pty_t *pty) 156 | { 157 | if(! pty) 158 | return(FALSE); 159 | 160 | close(pty->master_fd); 161 | close(pty->slave_fd); 162 | C_free(pty); 163 | 164 | return(TRUE); 165 | } 166 | 167 | #if !(defined HAVE_STROPTS_H || defined HAVE_OPENPTY) 168 | 169 | /* The following code comes from A.P.U.E. */ 170 | 171 | static int __C_pty_open_master_BSD(char *pts_name) 172 | { 173 | int fdm; 174 | char *ptr1, *ptr2; 175 | 176 | strcpy(pts_name, "/dev/ptyXY"); 177 | /* array index: 0123456789 (for references in following code) */ 178 | for(ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) 179 | { 180 | pts_name[8] = *ptr1; 181 | for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) 182 | { 183 | pts_name[9] = *ptr2; 184 | 185 | /* try to open master */ 186 | if((fdm = open(pts_name, O_RDWR)) < 0) 187 | { 188 | if(errno == ENOENT) /* different from EIO */ 189 | return(-1); /* out of pty devices */ 190 | else 191 | continue; /* try next pty device */ 192 | } 193 | 194 | pts_name[5] = 't'; /* change "pty" to "tty" */ 195 | return(fdm); /* got it, return fd of master */ 196 | } 197 | } 198 | return(-1); /* out of pty devices */ 199 | } 200 | 201 | /* 202 | */ 203 | 204 | static int __C_pty_open_slave_BSD(int fdm, char *pts_name) 205 | { 206 | struct group *grptr; 207 | int gid, fds; 208 | 209 | if((grptr = getgrnam("tty")) != NULL) 210 | gid = grptr->gr_gid; 211 | else 212 | gid = -1; /* group tty is not in the group file */ 213 | 214 | /* following two functions don't work unless we're root */ 215 | if(chown(pts_name, getuid(), gid) != 0) 216 | { 217 | close(fdm); 218 | return(-1); 219 | } 220 | 221 | if(chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP) != 0) 222 | { 223 | close(fdm); 224 | return(-1); 225 | } 226 | 227 | if((fds = open(pts_name, O_RDWR)) < 0) 228 | { 229 | close(fdm); 230 | return(-1); 231 | } 232 | 233 | return(fds); 234 | } 235 | 236 | #endif 237 | 238 | /* end of source file */ 239 | -------------------------------------------------------------------------------- /lib/random.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #ifdef THREADED_LIBRARY 30 | #include 31 | #endif /* THREADED_LIBRARY */ 32 | 33 | /* Local headers */ 34 | 35 | #include "cbase/defs.h" 36 | #include "cbase/system.h" 37 | 38 | /* File scope variables */ 39 | 40 | #ifdef THREADED_LIBRARY 41 | 42 | static pthread_once_t __C_random_once = PTHREAD_ONCE_INIT; 43 | static pthread_key_t __C_random_key; 44 | 45 | #endif /* THREADED_LIBRARY */ 46 | 47 | /* File scope functions */ 48 | 49 | #ifdef THREADED_LIBRARY 50 | 51 | static void __C_random_destructor(void *arg) 52 | { 53 | C_free(arg); 54 | } 55 | 56 | /* 57 | */ 58 | 59 | static void __C_random_init_once(void) 60 | { 61 | 62 | pthread_key_create(&__C_random_key, __C_random_destructor); 63 | } 64 | 65 | #endif /* THREADED_LIBRARY */ 66 | 67 | /* External functions */ 68 | 69 | void C_random_seed(void) 70 | { 71 | #ifdef THREADED_LIBRARY 72 | /* no-op */ 73 | #else 74 | 75 | #ifdef HAVE_SRANDDEV 76 | sranddev(); 77 | #else 78 | srand((uint_t)time(NULL) + (uint_t)getpid()); 79 | #endif 80 | 81 | #endif /* THREADED_LIBRARY */ 82 | } 83 | 84 | /* 85 | */ 86 | 87 | uint_t C_random(uint_t range) 88 | { 89 | uint_t r; 90 | 91 | #ifdef THREADED_LIBRARY 92 | uint_t *seed; 93 | 94 | pthread_once(&__C_random_once, __C_random_init_once); 95 | 96 | seed = (uint_t *)pthread_getspecific(__C_random_key); 97 | if(! seed) 98 | { 99 | seed = C_new(uint_t); 100 | *seed = (time(NULL) + (long)pthread_self()); 101 | pthread_setspecific(__C_random_key, (void *)seed); 102 | } 103 | 104 | r = (uint_t)rand_r(seed); 105 | #else 106 | r = (uint_t)rand(); 107 | #endif /* THREADED_LIBRARY */ 108 | 109 | return((int)((float)range * r / RAND_MAX)); 110 | } 111 | 112 | /* end of source file */ 113 | -------------------------------------------------------------------------------- /lib/sem.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | 32 | /* Local headers */ 33 | 34 | #include "cbase/defs.h" 35 | #include "cbase/ipc.h" 36 | #include "cbase/system.h" 37 | #include "cbase/util.h" 38 | 39 | /* Functions */ 40 | 41 | c_sem_t *C_sem_create(const char *name, mode_t mode, uint_t value) 42 | { 43 | c_sem_t *sem; 44 | sem_t *s; 45 | 46 | if((value < 1) || (value > C_SEM_MAX_VALUE)) 47 | return(NULL); 48 | 49 | if((s = sem_open(name, (O_CREAT | O_RDWR), mode, value)) 50 | == (sem_t *)SEM_FAILED) 51 | return(NULL); 52 | 53 | sem = C_new(c_sem_t); 54 | sem->sem = s; 55 | sem->name = C_string_dup(name); 56 | sem->initial_value = value; 57 | 58 | return(sem); 59 | } 60 | 61 | /* 62 | */ 63 | 64 | void C_sem_destroy(c_sem_t *sem) 65 | { 66 | if(!sem) 67 | return; 68 | 69 | sem_close(sem->sem); 70 | sem_unlink(sem->name); 71 | 72 | C_free(sem->name); 73 | C_free(sem); 74 | } 75 | 76 | /* 77 | */ 78 | 79 | c_bool_t C_sem_wait(c_sem_t *sem) 80 | { 81 | if(!sem || !(sem->sem)) 82 | return(FALSE); 83 | 84 | return(sem_wait(sem->sem) == 0); 85 | } 86 | 87 | /* 88 | */ 89 | 90 | c_bool_t C_sem_trywait(c_sem_t *sem) 91 | { 92 | if(!sem || !(sem->sem)) 93 | return(FALSE); 94 | 95 | return(sem_trywait(sem->sem) == 0); 96 | } 97 | 98 | /* 99 | */ 100 | 101 | c_bool_t C_sem_post(c_sem_t *sem) 102 | { 103 | if(!sem || !(sem->sem)) 104 | return(FALSE); 105 | 106 | return(sem_post(sem->sem) == 0); 107 | } 108 | 109 | /* 110 | */ 111 | 112 | int C_sem_value(c_sem_t *sem) 113 | { 114 | int val, r; 115 | 116 | if(!sem || !(sem->sem)) 117 | return(0); 118 | 119 | r = sem_getvalue(sem->sem, &val); 120 | 121 | return((r == 0) ? val : -1); 122 | } 123 | 124 | /* end of source file */ 125 | -------------------------------------------------------------------------------- /lib/shmem.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | #ifdef linux 28 | #define _XOPEN_SOURCE 500 29 | #endif 30 | 31 | /* System headers */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #ifdef linux 38 | #include /* Linux references a pthread struct in semaphore.h */ 39 | #endif 40 | 41 | /* Local headers */ 42 | 43 | #include "cbase/defs.h" 44 | #include "cbase/ipc.h" 45 | #include "cbase/system.h" 46 | #include "cbase/util.h" 47 | 48 | /* Functions */ 49 | 50 | static size_t __C_shmem_round_size(size_t size) 51 | { 52 | #if defined _SC_PAGESIZE 53 | long pagesize = sysconf(_SC_PAGESIZE); 54 | #elif defined HAVE_GETPAGESIZE 55 | long pagesize = getpagesize(); 56 | #else 57 | #error "No means to determine system page size." 58 | #endif 59 | 60 | return((size_t)(size + pagesize - (size % pagesize))); 61 | } 62 | 63 | /* 64 | */ 65 | 66 | c_shmem_t *C_shmem_create(const char *name, size_t size, mode_t mode) 67 | { 68 | c_shmem_t *m; 69 | int fd; 70 | c_bool_t init = TRUE; 71 | size_t rsize; 72 | 73 | if((fd = shm_open(name, (O_CREAT | O_RDWR | O_EXCL), mode)) < 0) 74 | { 75 | if(errno == EEXIST) 76 | { 77 | init = FALSE; 78 | 79 | if((fd = shm_open(name, (O_CREAT | O_RDWR), mode)) < 0) 80 | return(NULL); 81 | } 82 | else 83 | return(NULL); 84 | } 85 | 86 | rsize = __C_shmem_round_size(size); 87 | 88 | if(init) 89 | { 90 | if(ftruncate(fd, (off_t)rsize) != 0) 91 | return(NULL); 92 | } 93 | 94 | m = C_new(c_shmem_t); 95 | m->fd = fd; 96 | m->size = rsize; 97 | m->name = C_string_dup(name); 98 | m->base = mmap(NULL, m->size, (PROT_READ | PROT_WRITE), MAP_SHARED, m->fd, 99 | (off_t)0); 100 | 101 | 102 | if(init) 103 | memset(m->base, 0, m->size); 104 | 105 | return(m); 106 | } 107 | 108 | /* 109 | */ 110 | 111 | void C_shmem_destroy(c_shmem_t *mem) 112 | { 113 | if(!mem) 114 | return; 115 | 116 | munmap(mem->base, mem->size); 117 | shm_unlink(mem->name); 118 | C_free(mem->name); 119 | C_free(mem); 120 | } 121 | 122 | /* 123 | */ 124 | 125 | c_bool_t C_shmem_resize(c_shmem_t *mem, size_t size) 126 | { 127 | size_t oldsize, newsize; 128 | 129 | if(!mem || (size <= 0)) 130 | return(FALSE); 131 | 132 | oldsize = mem->size; 133 | newsize = __C_shmem_round_size(size); 134 | 135 | if(ftruncate(mem->fd, newsize)) 136 | return(FALSE); 137 | 138 | mem->size = newsize; 139 | if(newsize > oldsize) 140 | memset(mem->base + oldsize, 0, (newsize - oldsize)); 141 | 142 | return(TRUE); 143 | } 144 | 145 | /* end of source file */ 146 | -------------------------------------------------------------------------------- /lib/signals.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* Local headers */ 28 | 29 | #include "cbase/defs.h" 30 | #include "cbase/ipc.h" 31 | #include "cbase/system.h" 32 | 33 | /* System headers */ 34 | 35 | #include 36 | 37 | /* File scope variables */ 38 | 39 | static const char *__C_sig_names[] = 40 | { 41 | "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", "SIGABRT", "SIGEMT", 42 | "SIGFPE", "SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", 43 | "SIGTERM", "SIGUSR1", "SIGUSR2", "SIGCHLD", "SIGPWR", "SIGWINCH", "SIGURG", 44 | "SIGPOLL", "SIGIO", "SIGSTOP", "SIGTSTP", "SIGCONT", "SIGTTIN", "SIGTTOU", 45 | "SIGVTALRM", "SIGPROF", "SIGXCPU", "SIGXFSZ" 46 | }; 47 | 48 | /* Functions */ 49 | 50 | const char *C_signal_name(int sig) 51 | { 52 | if(sig < C_SIGNAL_MIN || sig > C_SIGNAL_MAX) 53 | return(NULL); 54 | 55 | return(__C_sig_names[--sig]); 56 | } 57 | 58 | /* end of source file */ 59 | -------------------------------------------------------------------------------- /lib/strbuf.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | 32 | /* Local headers */ 33 | 34 | #include "cbase/defs.h" 35 | #include "cbase/system.h" 36 | #include "cbase/util.h" 37 | 38 | /* Functions */ 39 | 40 | c_strbuffer_t *C_strbuffer_create(size_t bufsz) 41 | { 42 | c_strbuffer_t *sb; 43 | 44 | if(bufsz < 1) 45 | return(FALSE); 46 | 47 | sb = C_new(c_strbuffer_t); 48 | 49 | sb->bufsz = bufsz; 50 | sb->left = sb->bufsz - 1; 51 | sb->buf = sb->pos = C_newstr(sb->bufsz); 52 | *(sb->pos) = NUL; 53 | 54 | return(sb); 55 | } 56 | 57 | /* 58 | */ 59 | 60 | c_bool_t C_strbuffer_destroy(c_strbuffer_t *sb) 61 | { 62 | if(!sb) 63 | return(FALSE); 64 | 65 | C_free(sb->buf); 66 | C_free(sb); 67 | 68 | return(TRUE); 69 | } 70 | 71 | /* 72 | */ 73 | 74 | c_bool_t C_strbuffer_clear(c_strbuffer_t *sb) 75 | { 76 | if(! sb) 77 | return(FALSE); 78 | 79 | sb->pos = sb->buf; 80 | sb->left = sb->bufsz - 1; 81 | *(sb->pos) = NUL; 82 | 83 | return(TRUE); 84 | } 85 | 86 | /* 87 | */ 88 | 89 | c_bool_t C_strbuffer_strcpy(c_strbuffer_t *sb, const char *s) 90 | { 91 | 92 | if(!sb || !s) 93 | return(FALSE); 94 | 95 | if(C_strbuffer_clear(sb)) 96 | return(C_strbuffer_strcat(sb, s)); 97 | 98 | return(FALSE); 99 | } 100 | 101 | /* 102 | */ 103 | 104 | c_bool_t C_strbuffer_strcat(c_strbuffer_t *sb, const char *s) 105 | { 106 | c_bool_t ok = TRUE; 107 | size_t l; 108 | 109 | if(!sb || !s) 110 | return(FALSE); 111 | 112 | l = strlen(s); 113 | 114 | if(l > sb->left) 115 | { 116 | l = sb->left; 117 | ok = FALSE; 118 | } 119 | 120 | strncpy(sb->pos, s, l); 121 | sb->pos += l; 122 | sb->left -= l; 123 | *(sb->pos) = NUL; 124 | 125 | return(ok); 126 | } 127 | 128 | /* 129 | */ 130 | 131 | c_bool_t C_strbuffer_sprintf(c_strbuffer_t *sb, const char *s, ...) 132 | { 133 | va_list vp; 134 | int l; 135 | c_bool_t ok = TRUE; 136 | 137 | if(!sb || !s) 138 | return(FALSE); 139 | 140 | va_start(vp, s); 141 | l = vsnprintf(sb->pos, sb->left, s, vp); 142 | va_end(vp); 143 | 144 | if(l > sb->left) 145 | { 146 | l = sb->left; 147 | ok = FALSE; 148 | } 149 | 150 | sb->pos += l; 151 | sb->left -= l; 152 | *(sb->pos) = NUL; 153 | 154 | return(ok); 155 | } 156 | 157 | /* 158 | */ 159 | 160 | c_bool_t C_strbuffer_putc(c_strbuffer_t *sb, char c) 161 | { 162 | if(!sb || (c == NUL)) 163 | return(FALSE); 164 | 165 | if(sb->left < 1) 166 | return(FALSE); 167 | 168 | *(sb->pos) = c; 169 | 170 | --sb->left; 171 | ++sb->pos; 172 | 173 | return(TRUE); 174 | } 175 | 176 | /* 177 | */ 178 | 179 | size_t C_strbuffer_strlen(c_strbuffer_t *sb) 180 | { 181 | if(!sb) 182 | return(0); 183 | 184 | return(strlen(sb->buf)); 185 | } 186 | 187 | /* end of source file */ 188 | -------------------------------------------------------------------------------- /lib/system.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #ifdef HAVE_CRYPT_H 34 | #include 35 | #endif 36 | #include 37 | 38 | /* Local headers */ 39 | 40 | #include "cbase/defs.h" 41 | #include "cbase/system.h" 42 | #include "cbase/util.h" 43 | 44 | /* Macros */ 45 | 46 | #define C_SYSTEM_SALT_STRLEN 64 47 | 48 | /* File scope variables */ 49 | 50 | static const char *__C_system_salt_string = "abcdefghijklmnopqrstuvwxyz" \ 51 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; 52 | 53 | static c_sysinfo_t *__C_system_info = NULL; 54 | 55 | /* Functions */ 56 | 57 | c_bool_t C_system_ingroup(const char *login, const char *group) 58 | { 59 | c_bool_t foundf = FALSE; 60 | struct group gr; 61 | struct group *rgr; 62 | struct passwd pw; 63 | struct passwd *rpw; 64 | char **u, *buf = NULL; 65 | gid_t gid; 66 | int blk = 128, x; 67 | 68 | if(!login || !group) 69 | return(FALSE); 70 | if(!*login || !*group) 71 | return(FALSE); 72 | 73 | buf = C_malloc(blk, char); 74 | 75 | GETPWNAM: 76 | x = getpwnam_r(login, &pw, buf, blk, &rpw); 77 | 78 | if(x == ERANGE) 79 | { 80 | blk += 128; 81 | buf = C_realloc(buf, blk, char); 82 | goto GETPWNAM; 83 | } 84 | else if(rpw == NULL) 85 | { 86 | C_free(buf); 87 | return(FALSE); 88 | } 89 | 90 | gid = rpw->pw_gid; 91 | 92 | GETGRNAM: 93 | #ifndef HAVE_GETGRNAM_R 94 | #warning "getgrnam_r() not available; C_system_isingroup() won't be re-entrant" 95 | rgr = getgrnam(group); 96 | #else 97 | x = getgrnam_r(group, &gr, buf, blk, &rgr); 98 | #endif 99 | if(x == ERANGE) 100 | { 101 | blk += 128; 102 | buf = C_realloc(buf, blk, char); 103 | goto GETGRNAM; 104 | } 105 | else if(x != 0) 106 | { 107 | C_free(buf); 108 | return(FALSE); 109 | } 110 | 111 | if(gid == rgr->gr_gid) /* primary group? */ 112 | foundf = TRUE; 113 | else 114 | { 115 | for(u = rgr->gr_mem; *u; u++) 116 | { 117 | if(!strcmp(*u, login)) 118 | { 119 | foundf = TRUE; 120 | break; 121 | } 122 | } 123 | } 124 | 125 | C_free(buf); 126 | return(foundf); 127 | } 128 | 129 | /* 130 | */ 131 | 132 | c_sysinfo_t *C_system_getinfo(void) 133 | { 134 | static struct passwd *pw = NULL; 135 | struct passwd *rpw; 136 | struct utsname uts; 137 | char *buf; 138 | int blk = 128, x; 139 | 140 | if(!pw) 141 | pw = C_new(struct passwd); 142 | 143 | if(!__C_system_info) 144 | { 145 | __C_system_info = C_new(c_sysinfo_t); 146 | 147 | buf = C_newstr(blk); 148 | 149 | __C_system_info->uid = getuid(); 150 | 151 | GETPWUID: 152 | x = getpwuid_r(__C_system_info->uid, pw, buf, blk, &rpw); 153 | 154 | if(x == ERANGE) 155 | { 156 | blk += 128; 157 | buf = C_realloc(buf, blk, char); 158 | goto GETPWUID; 159 | } 160 | 161 | if(pw) 162 | { 163 | char *p; 164 | 165 | __C_system_info->login = C_string_dup(pw->pw_name); 166 | __C_system_info->fullname = C_string_dup(pw->pw_gecos); 167 | 168 | if((p = strchr(__C_system_info->fullname, ',')) != NULL) 169 | *p = NUL; 170 | 171 | __C_system_info->homedir = C_string_dup(pw->pw_dir); 172 | __C_system_info->shell = C_string_dup(pw->pw_shell); 173 | } 174 | else 175 | { 176 | __C_system_info->login = NULL; 177 | __C_system_info->fullname = NULL; 178 | __C_system_info->homedir = NULL; 179 | __C_system_info->shell = NULL; 180 | } 181 | 182 | C_free(buf); 183 | 184 | __C_system_info->gid = getgid(); 185 | __C_system_info->euid = geteuid(); 186 | __C_system_info->egid = getegid(); 187 | 188 | uname(&uts); 189 | __C_system_info->hostname = C_string_dup(uts.nodename); 190 | __C_system_info->osname = C_string_dup(uts.sysname); 191 | __C_system_info->osver = C_string_dup(uts.version); 192 | __C_system_info->osrel = C_string_dup(uts.release); 193 | __C_system_info->arch = C_string_dup(uts.machine); 194 | 195 | __C_system_info->pid = getpid(); 196 | __C_system_info->ppid = getppid(); 197 | __C_system_info->stime = time(NULL); 198 | __C_system_info->term = C_newstr(L_ctermid); 199 | #ifdef HAVE_CTERMID_R 200 | ctermid_r(__C_system_info->term); 201 | #else 202 | ctermid(__C_system_info->term); 203 | #endif 204 | __C_system_info->term[L_ctermid] = NUL; 205 | } 206 | 207 | return(__C_system_info); 208 | } 209 | 210 | /* 211 | */ 212 | 213 | c_bool_t C_system_cdhome(void) 214 | { 215 | char *p = C_system_get_homedir(); 216 | c_bool_t r = (chdir(p) ? FALSE : TRUE); 217 | 218 | C_free(p); 219 | return(r); 220 | } 221 | 222 | /* 223 | */ 224 | 225 | uid_t C_system_get_uid(void) 226 | { 227 | return(C_system_getinfo()->uid); 228 | } 229 | 230 | /* 231 | */ 232 | 233 | gid_t C_system_get_gid(void) 234 | { 235 | return(C_system_getinfo()->gid); 236 | } 237 | 238 | /* 239 | */ 240 | 241 | pid_t C_system_get_pid(void) 242 | { 243 | return(C_system_getinfo()->pid); 244 | } 245 | 246 | /* 247 | */ 248 | 249 | char *C_system_get_login(void) 250 | { 251 | return(C_system_getinfo()->login); 252 | } 253 | 254 | /* 255 | */ 256 | 257 | char *C_system_get_fullname(void) 258 | { 259 | return(C_system_getinfo()->fullname); 260 | } 261 | 262 | /* 263 | */ 264 | 265 | char *C_system_get_homedir(void) 266 | { 267 | return(C_system_getinfo()->homedir); 268 | } 269 | 270 | /* 271 | */ 272 | 273 | char *C_system_get_hostname(void) 274 | { 275 | return(C_system_getinfo()->hostname); 276 | } 277 | 278 | /* 279 | */ 280 | 281 | char *C_system_get_term(void) 282 | { 283 | return(C_system_getinfo()->term); 284 | } 285 | 286 | /* 287 | */ 288 | 289 | c_bool_t C_system_passwd_validate(const char *plaintext, 290 | const char *ciphertext) 291 | { 292 | char salt[3], *c; 293 | 294 | strncpy(salt, ciphertext, 2); 295 | 296 | c = (char *)crypt(plaintext, salt); 297 | 298 | return(!strcmp(c, ciphertext)); 299 | } 300 | 301 | /* 302 | */ 303 | 304 | c_bool_t C_system_passwd_generate(const char *plaintext, char *buf, 305 | size_t bufsz) 306 | { 307 | char salt[2], *cp; 308 | 309 | if(!plaintext || !buf || !bufsz) 310 | return(FALSE); 311 | 312 | salt[0] = __C_system_salt_string[C_random(C_SYSTEM_SALT_STRLEN)]; 313 | salt[1] = __C_system_salt_string[C_random(C_SYSTEM_SALT_STRLEN)]; 314 | 315 | cp = (char *)crypt(plaintext, salt); 316 | 317 | strncpy(buf, cp, bufsz - 1); 318 | *(buf + bufsz - 1) = NUL; 319 | 320 | return(TRUE); 321 | } 322 | 323 | /* end of source file */ 324 | -------------------------------------------------------------------------------- /lib/template.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | /* System headers */ 26 | 27 | /* Local headers */ 28 | 29 | /* Macros */ 30 | 31 | /* File scope variables */ 32 | 33 | /* External variables */ 34 | 35 | /* File scope functions */ 36 | 37 | /* External functions */ 38 | 39 | /* Structures and unions */ 40 | 41 | /* Signal handler functions */ 42 | 43 | /* Functions */ 44 | 45 | /* Main */ 46 | 47 | /* end of source file */ 48 | -------------------------------------------------------------------------------- /lib/time.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | #ifdef linux 28 | #define _XOPEN_SOURCE 500 29 | #endif 30 | 31 | /* System headers */ 32 | 33 | #include 34 | 35 | /* Local headers */ 36 | 37 | #include "cbase/defs.h" 38 | 39 | /* Functions */ 40 | 41 | c_bool_t C_time_format(time_t t, char *buf, size_t bufsz, const char *format) 42 | { 43 | time_t t1; 44 | struct tm t2; 45 | 46 | t1 = (t ? t : time(NULL)); 47 | (void)localtime_r(&t1, &t2); 48 | 49 | return((strftime(buf, bufsz, format, &t2) > 0) ? TRUE : FALSE); 50 | } 51 | 52 | /* 53 | */ 54 | 55 | time_t C_time_parse(const char *buf, const char *format) 56 | { 57 | struct tm t; 58 | 59 | if(! strptime(buf, format, &t)) 60 | return((time_t)0); 61 | 62 | return(mktime(&t)); 63 | } 64 | 65 | /* end of source file */ 66 | -------------------------------------------------------------------------------- /lib/timer.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | 24 | /* Feature test switches */ 25 | 26 | #include "config.h" 27 | 28 | /* System headers */ 29 | 30 | #include 31 | 32 | /* Local headers */ 33 | 34 | #include "cbase/defs.h" 35 | #include "cbase/system.h" 36 | #include "cbase/util.h" 37 | 38 | /* Functions */ 39 | 40 | c_timer_t *C_timer_create(void) 41 | { 42 | c_timer_t *timer = C_new(c_timer_t); 43 | 44 | time(&(timer->created)); /* set creation time on timer */ 45 | 46 | timer->running = FALSE; 47 | 48 | return(timer); 49 | } 50 | 51 | /* 52 | */ 53 | 54 | void C_timer_destroy(c_timer_t *timer) 55 | { 56 | C_free(timer); 57 | } 58 | 59 | /* 60 | */ 61 | 62 | void C_timer_start(c_timer_t *timer) 63 | { 64 | if(! timer->running) 65 | { 66 | timer->usr_time = timer->sys_time = timer->real_time = 0; 67 | times(&(timer->t1)); 68 | gettimeofday(&(timer->tv1), NULL); 69 | 70 | timer->running = TRUE; 71 | } 72 | } 73 | 74 | /* 75 | */ 76 | 77 | void C_timer_resume(c_timer_t *timer) 78 | { 79 | if(! timer->running) 80 | { 81 | times(&(timer->t1)); 82 | gettimeofday(&(timer->tv1), NULL); 83 | 84 | timer->running = TRUE; 85 | } 86 | } 87 | 88 | /* 89 | */ 90 | 91 | void C_timer_stop(c_timer_t *timer) 92 | { 93 | long clk_tck = sysconf(_SC_CLK_TCK); 94 | 95 | if(timer->running) 96 | { 97 | times(&(timer->t2)); 98 | gettimeofday(&(timer->tv2), NULL); 99 | 100 | timer->usr = (timer->t2.tms_utime - timer->t1.tms_utime); 101 | timer->sys = (timer->t2.tms_stime - timer->t1.tms_stime); 102 | timer->real = ((timer->tv2.tv_sec * 1000 + timer->tv2.tv_usec) 103 | - (timer->tv1.tv_sec * 1000 + timer->tv1.tv_usec)); 104 | 105 | timer->usr_time += ((float)(timer->usr) / (float)clk_tck); 106 | timer->sys_time += ((float)(timer->sys) / (float)clk_tck); 107 | timer->real_time += timer->real; 108 | 109 | timer->running = FALSE; 110 | } 111 | } 112 | 113 | /* 114 | */ 115 | 116 | void C_timer_reset(c_timer_t *timer) 117 | { 118 | timer->running = FALSE; 119 | timer->usr_time = timer->sys_time = timer->real_time = 0; 120 | } 121 | 122 | /* end of source file */ 123 | -------------------------------------------------------------------------------- /lib/tty.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* System headers */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | /* Local headers */ 35 | 36 | #include "cbase/defs.h" 37 | #include "cbase/ipc.h" 38 | #include "cbase/cerrno.h" 39 | #include "cbase/system.h" 40 | 41 | /* File scope variables */ 42 | 43 | static struct termios __C_tty_mode; 44 | static struct termios __C_tty_buf; 45 | static c_bool_t __C_tty_rawf = FALSE; 46 | static c_bool_t __C_tty_storef = FALSE; 47 | 48 | /* Functions */ 49 | 50 | c_bool_t C_tty_raw(int fd) 51 | { 52 | struct termios t; 53 | 54 | if(!isatty(fd)) 55 | { 56 | C_error_set_errno(C_ENOTTY); 57 | return(FALSE); 58 | } 59 | 60 | if(tcgetattr(fd, &t)) 61 | { 62 | C_error_set_errno(C_ETCATTR); 63 | return(FALSE); 64 | } 65 | 66 | __C_tty_mode = t; /* save tty mode */ 67 | 68 | t.c_iflag = 0; 69 | t.c_oflag &= ~OPOST; 70 | t.c_lflag &= ~(ECHO | ICANON | ISIG); 71 | t.c_cflag &= ~(CSIZE | PARENB); 72 | t.c_cflag |= CS8; 73 | t.c_cc[VMIN] = t.c_cc[VTIME] = 1; 74 | 75 | if(tcsetattr(fd, TCSANOW, &t)) 76 | { 77 | C_error_set_errno(C_ETCATTR); 78 | return(FALSE); 79 | } 80 | 81 | __C_tty_rawf = TRUE; 82 | 83 | return(TRUE); 84 | } 85 | 86 | /* 87 | */ 88 | 89 | c_bool_t C_tty_unraw(int fd) 90 | { 91 | 92 | if(!isatty(fd)) 93 | { 94 | C_error_set_errno(C_ENOTTY); 95 | return(FALSE); 96 | } 97 | 98 | if(!__C_tty_rawf) 99 | { 100 | C_error_set_errno(C_EINVAL); 101 | return(FALSE); 102 | } 103 | 104 | if(!tcsetattr(fd, TCSANOW, &(__C_tty_mode))) 105 | { 106 | C_error_set_errno(C_ETCATTR); 107 | return(FALSE); 108 | } 109 | 110 | return(TRUE); 111 | } 112 | 113 | /* 114 | */ 115 | 116 | c_bool_t C_tty_store(int fd) 117 | { 118 | 119 | if(!isatty(fd)) 120 | { 121 | C_error_set_errno(C_ENOTTY); 122 | return(FALSE); 123 | } 124 | 125 | if(!tcgetattr(fd, &(__C_tty_buf))) 126 | { 127 | C_error_set_errno(C_ETCATTR); 128 | return(FALSE); 129 | } 130 | 131 | __C_tty_storef = TRUE; 132 | return(TRUE); 133 | } 134 | 135 | /* 136 | */ 137 | 138 | c_bool_t C_tty_restore(int fd) 139 | { 140 | 141 | if(!isatty(fd)) 142 | { 143 | C_error_set_errno(C_ENOTTY); 144 | return(FALSE); 145 | } 146 | 147 | if(!__C_tty_storef) 148 | { 149 | C_error_set_errno(C_EINVAL); 150 | return(FALSE); 151 | } 152 | 153 | if(!tcsetattr(fd, TCSANOW, &(__C_tty_buf))) 154 | { 155 | C_error_set_errno(C_ETCATTR); 156 | return(FALSE); 157 | } 158 | 159 | return(TRUE); 160 | } 161 | 162 | /* 163 | */ 164 | 165 | c_bool_t C_tty_sane(int fd) 166 | { 167 | int i; 168 | 169 | if(!isatty(fd)) 170 | { 171 | C_error_set_errno(C_ENOTTY); 172 | return(FALSE); 173 | } 174 | 175 | memset((void *)&__C_tty_buf, 0, sizeof(struct termios)); 176 | 177 | __C_tty_buf.c_iflag = ICRNL | IXON | IXOFF; 178 | __C_tty_buf.c_oflag = OPOST; 179 | __C_tty_buf.c_cflag = CREAD | HUPCL; 180 | __C_tty_buf.c_lflag = ECHO | ECHOE | ECHOK | ICANON | ISIG | IEXTEN; 181 | 182 | for(i = 0; i < NCCS; i++) 183 | __C_tty_buf.c_cc[i] = -1; 184 | 185 | __C_tty_buf.c_cc[VEOF] = 3; 186 | __C_tty_buf.c_cc[VEOL] = 28; 187 | __C_tty_buf.c_cc[VERASE] = 8; 188 | __C_tty_buf.c_cc[VINTR] = 21; 189 | __C_tty_buf.c_cc[VKILL] = 4; 190 | __C_tty_buf.c_cc[VQUIT] = 255; 191 | __C_tty_buf.c_cc[VSUSP] = 255; 192 | __C_tty_buf.c_cc[VSTART] = 17; 193 | __C_tty_buf.c_cc[VSTOP] = 19; 194 | 195 | if(!tcsetattr(fd, TCSANOW, &(__C_tty_buf))) 196 | { 197 | C_error_set_errno(C_ETCATTR); 198 | return(FALSE); 199 | } 200 | 201 | return(TRUE); 202 | } 203 | 204 | /* 205 | */ 206 | 207 | c_bool_t C_tty_getsize(uint_t *columns, uint_t *rows) 208 | { 209 | if(! isatty(STDOUT_FILENO)) 210 | return(FALSE); 211 | 212 | #if defined(TIOCGWINSZ) 213 | 214 | { 215 | struct winsize ws; 216 | 217 | if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) 218 | { 219 | if(columns) 220 | *columns = ws.ws_col; 221 | if(rows) 222 | *rows = ws.ws_row; 223 | return(TRUE); 224 | } 225 | else 226 | return(FALSE); 227 | } 228 | 229 | #elif defined(TIOCGSIZE) 230 | 231 | { 232 | struct ttysize ts; 233 | 234 | if(ioctl(STDOUT_FILENO, TIOCGSIZE, &ts) == 0) 235 | { 236 | if(columns) 237 | *columns = ts.ts_cols; 238 | if(rows) 239 | *rows = ts.ts_lines; 240 | return(TRUE); 241 | } 242 | else 243 | return(FALSE); 244 | } 245 | 246 | #else 247 | 248 | #warning No way to determine terminal size. 249 | 250 | return(FALSE); 251 | 252 | #endif 253 | } 254 | 255 | /* end of source file */ 256 | -------------------------------------------------------------------------------- /lib/vector.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* Local headers */ 28 | 29 | #include "cbase/defs.h" 30 | #include "cbase/system.h" 31 | #include "cbase/util.h" 32 | 33 | /* Functions */ 34 | 35 | c_vector_t *C_vector_start(uint_t resize_rate) 36 | { 37 | c_vector_t *v = C_new(c_vector_t); 38 | 39 | v->len = v->c = 0; 40 | v->vs = v->v = C_newa(resize_rate, char *); 41 | v->blk = 1; 42 | v->blksz = resize_rate; 43 | 44 | return(v); 45 | } 46 | 47 | /* 48 | */ 49 | 50 | c_bool_t C_vector_store(c_vector_t *v, const char *s) 51 | { 52 | 53 | if(!v || !s) 54 | return(FALSE); 55 | 56 | *(v->v) = (char *)s; 57 | (v->len)++; 58 | if(++(v->c) == v->blksz) 59 | { 60 | v->c = 0; 61 | v->vs = C_realloc(v->vs, v->blksz * ++(v->blk), char *); 62 | v->v = v->vs + ((v->blk - 1) * v->blksz); 63 | } 64 | else 65 | ++(v->v); 66 | 67 | return(TRUE); 68 | } 69 | 70 | /* 71 | */ 72 | 73 | char **C_vector_end(c_vector_t *v, size_t *len) 74 | { 75 | char **r; 76 | 77 | if(!v) 78 | return(NULL); 79 | 80 | if(len) 81 | *len = (size_t)v->len; 82 | 83 | r = C_realloc(v->vs, ++(v->len), char *); 84 | *(r + v->len - 1) = NULL; 85 | C_free(v); 86 | 87 | return(r); 88 | } 89 | 90 | /* 91 | */ 92 | 93 | c_bool_t C_vector_contains(c_vector_t *v, const char *s) 94 | { 95 | char **p; 96 | uint_t len; 97 | 98 | if(!v || !s) 99 | return(FALSE); 100 | 101 | for(p = v->vs, len = v->len; len--; ++p) 102 | { 103 | if(! strcmp(*p, s)) 104 | return(TRUE); 105 | } 106 | 107 | return(FALSE); 108 | } 109 | 110 | /* 111 | */ 112 | 113 | void C_vector_abort(c_vector_t *v) 114 | { 115 | 116 | if(v) 117 | { 118 | C_free_vec(v->vs); 119 | C_free(v); 120 | } 121 | } 122 | 123 | /* end of source file */ 124 | -------------------------------------------------------------------------------- /lib/version.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | cbase - A C Foundation Library 3 | Copyright (C) 1994-2025 Mark A Lindner 4 | 5 | This file is part of cbase. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with this library; if not, see 19 | . 20 | ---------------------------------------------------------------------------- 21 | */ 22 | 23 | /* Feature test switches */ 24 | 25 | #include "config.h" 26 | 27 | /* Local headers */ 28 | 29 | #include "cbase/defs.h" 30 | 31 | /* File scope variables */ 32 | 33 | static const char *__c_version = PACKAGE_VERSION; 34 | 35 | static const char *__c_info = PACKAGE_STRING \ 36 | " - (C) 1994-2025 Mark A Lindner - " PACKAGE_BUGREPORT; 37 | 38 | static const char *__c_options[] = { 39 | #ifdef THREADED_LIBRARY 40 | "threaded", 41 | #endif /* THREADED_LIBRARY */ 42 | 43 | #ifdef HAVE_LIBEXPAT 44 | "xml", 45 | #endif /* HAVE_LIBEXPAT */ 46 | NULL 47 | }; 48 | 49 | /* External functions */ 50 | 51 | const char *C_library_version(void) 52 | { 53 | return(__c_version); 54 | } 55 | 56 | /* 57 | */ 58 | 59 | const char *C_library_info(void) 60 | { 61 | return(__c_info); 62 | } 63 | 64 | /* 65 | */ 66 | 67 | const char **C_library_options(void) 68 | { 69 | return(__c_options); 70 | } 71 | 72 | /* end of source file */ 73 | -------------------------------------------------------------------------------- /m4/ltsugar.m4: -------------------------------------------------------------------------------- 1 | # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2024 Free Software 4 | # Foundation, Inc. 5 | # Written by Gary V. Vaughan, 2004 6 | # 7 | # This file is free software; the Free Software Foundation gives 8 | # unlimited permission to copy and/or distribute it, with or without 9 | # modifications, as long as this notice is preserved. 10 | 11 | # serial 6 ltsugar.m4 12 | 13 | # This is to help aclocal find these macros, as it can't see m4_define. 14 | AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) 15 | 16 | 17 | # lt_join(SEP, ARG1, [ARG2...]) 18 | # ----------------------------- 19 | # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their 20 | # associated separator. 21 | # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier 22 | # versions in m4sugar had bugs. 23 | m4_define([lt_join], 24 | [m4_if([$#], [1], [], 25 | [$#], [2], [[$2]], 26 | [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) 27 | m4_define([_lt_join], 28 | [m4_if([$#$2], [2], [], 29 | [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) 30 | 31 | 32 | # lt_car(LIST) 33 | # lt_cdr(LIST) 34 | # ------------ 35 | # Manipulate m4 lists. 36 | # These macros are necessary as long as will still need to support 37 | # Autoconf-2.59, which quotes differently. 38 | m4_define([lt_car], [[$1]]) 39 | m4_define([lt_cdr], 40 | [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], 41 | [$#], 1, [], 42 | [m4_dquote(m4_shift($@))])]) 43 | m4_define([lt_unquote], $1) 44 | 45 | 46 | # lt_append(MACRO-NAME, STRING, [SEPARATOR]) 47 | # ------------------------------------------ 48 | # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. 49 | # Note that neither SEPARATOR nor STRING are expanded; they are appended 50 | # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). 51 | # No SEPARATOR is output if MACRO-NAME was previously undefined (different 52 | # than defined and empty). 53 | # 54 | # This macro is needed until we can rely on Autoconf 2.62, since earlier 55 | # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. 56 | m4_define([lt_append], 57 | [m4_define([$1], 58 | m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) 59 | 60 | 61 | 62 | # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) 63 | # ---------------------------------------------------------- 64 | # Produce a SEP delimited list of all paired combinations of elements of 65 | # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list 66 | # has the form PREFIXmINFIXSUFFIXn. 67 | # Needed until we can rely on m4_combine added in Autoconf 2.62. 68 | m4_define([lt_combine], 69 | [m4_if(m4_eval([$# > 3]), [1], 70 | [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl 71 | [[m4_foreach([_Lt_prefix], [$2], 72 | [m4_foreach([_Lt_suffix], 73 | ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, 74 | [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) 75 | 76 | 77 | # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) 78 | # ----------------------------------------------------------------------- 79 | # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited 80 | # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. 81 | m4_define([lt_if_append_uniq], 82 | [m4_ifdef([$1], 83 | [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], 84 | [lt_append([$1], [$2], [$3])$4], 85 | [$5])], 86 | [lt_append([$1], [$2], [$3])$4])]) 87 | 88 | 89 | # lt_dict_add(DICT, KEY, VALUE) 90 | # ----------------------------- 91 | m4_define([lt_dict_add], 92 | [m4_define([$1($2)], [$3])]) 93 | 94 | 95 | # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) 96 | # -------------------------------------------- 97 | m4_define([lt_dict_add_subkey], 98 | [m4_define([$1($2:$3)], [$4])]) 99 | 100 | 101 | # lt_dict_fetch(DICT, KEY, [SUBKEY]) 102 | # ---------------------------------- 103 | m4_define([lt_dict_fetch], 104 | [m4_ifval([$3], 105 | m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), 106 | m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) 107 | 108 | 109 | # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) 110 | # ----------------------------------------------------------------- 111 | m4_define([lt_if_dict_fetch], 112 | [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], 113 | [$5], 114 | [$6])]) 115 | 116 | 117 | # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) 118 | # -------------------------------------------------------------- 119 | m4_define([lt_dict_filter], 120 | [m4_if([$5], [], [], 121 | [lt_join(m4_quote(m4_default([$4], [[, ]])), 122 | lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), 123 | [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl 124 | ]) 125 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004, 2011-2019, 2021-2024 Free Software Foundation, 4 | # Inc. 5 | # Written by Scott James Remnant, 2004 6 | # 7 | # This file is free software; the Free Software Foundation gives 8 | # unlimited permission to copy and/or distribute it, with or without 9 | # modifications, as long as this notice is preserved. 10 | 11 | # @configure_input@ 12 | 13 | # serial 4441 ltversion.m4 14 | # This file is part of GNU Libtool 15 | 16 | m4_define([LT_PACKAGE_VERSION], [2.5.4]) 17 | m4_define([LT_PACKAGE_REVISION], [2.5.4]) 18 | 19 | AC_DEFUN([LTVERSION_VERSION], 20 | [macro_version='2.5.4' 21 | macro_revision='2.5.4' 22 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 23 | _LT_DECL(, macro_revision, 0) 24 | ]) 25 | -------------------------------------------------------------------------------- /m4/lt~obsolete.m4: -------------------------------------------------------------------------------- 1 | # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004. 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 5 lt~obsolete.m4 11 | 12 | # These exist entirely to fool aclocal when bootstrapping libtool. 13 | # 14 | # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) 15 | # which have later been changed to m4_define as they aren't part of the 16 | # exported API, or moved to Autoconf or Automake where they belong. 17 | # 18 | # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN 19 | # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us 20 | # using a macro with the same name in our local m4/libtool.m4 it'll 21 | # pull the old libtool.m4 in (it doesn't see our shiny new m4_define 22 | # and doesn't know about Autoconf macros at all.) 23 | # 24 | # So we provide this file, which has a silly filename so it's always 25 | # included after everything else. This provides aclocal with the 26 | # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything 27 | # because those macros already exist, or will be overwritten later. 28 | # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 29 | # 30 | # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. 31 | # Yes, that means every name once taken will need to remain here until 32 | # we give up compatibility with versions before 1.7, at which point 33 | # we need to keep only those names which we still refer to. 34 | 35 | # This is to help aclocal find these macros, as it can't see m4_define. 36 | AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) 37 | 38 | m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) 39 | m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) 40 | m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) 41 | m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) 42 | m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) 43 | m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) 44 | m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) 45 | m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) 46 | m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) 47 | m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) 48 | m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) 49 | m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) 50 | m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) 51 | m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) 52 | m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) 53 | m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) 54 | m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) 55 | m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) 56 | m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) 57 | m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) 58 | m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) 59 | m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) 60 | m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) 61 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) 62 | m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) 63 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) 64 | m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) 65 | m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) 66 | m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) 67 | m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) 68 | m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) 69 | m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) 70 | m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) 71 | m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) 72 | m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) 73 | m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) 74 | m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) 75 | m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) 76 | m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) 77 | m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) 78 | m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) 79 | m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) 80 | m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) 81 | m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) 82 | m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) 83 | m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) 84 | m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) 85 | m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) 86 | m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) 87 | m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) 88 | m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) 89 | m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) 90 | m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) 91 | m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) 92 | m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) 93 | m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) 94 | m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) 95 | m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) 96 | m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) 97 | m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) 98 | m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) 99 | --------------------------------------------------------------------------------