Compare commits

..
52 Commits
Author SHA1 Message Date
Joachim Wiberg 95e5fdba9b Bump version for v2.5.0 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-30 07:01:09 +01:00
Joachim Wiberg b21d1c8e9b More syntactic sugar
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 18:49:20 +01:00
Joachim Wiberg 5b670951a3 More experimenting and some reflow of a paragraph
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 00:33:10 +01:00
Joachim Wiberg 612290c9e2 Experiment with syntax highlighting
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 00:28:39 +01:00
Joachim Wiberg 80d11dccf7 Update changelogs for upcoming v2.5.0 release
This should be it, but let's sleep on it for good measure.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 00:25:53 +01:00
Joachim Wiberg 438e7a2722 debian: update libite-dev, headers in libite/*.h and lite symlink
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 00:25:21 +01:00
Joachim Wiberg 96e023e58e Update README wrt the namespace change
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 00:23:24 +01:00
Joachim Wiberg 67a9b379ba Update comments, also namespace is one word
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-29 00:22:38 +01:00
Joachim Wiberg 1c0988b8e2 Fix #18: optional compat symlink lite -> libite/
Default is to create the symlink, to facilitate upgrades.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-28 19:22:45 +01:00
Joachim Wiberg 407b8f6dbf Prefix include guards with LIBITE_ to safe guard name space
The tree.h and queue.h include guards must remain so users don't
accidentally get their system queue.h included as well.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-28 19:20:53 +01:00
Joachim Wiberg bc72e1c3ad Change -lite include path/name space; lite/*.h -> libite/*.h
First step in fixing issue #18.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-28 19:09:55 +01:00
Joachim Wiberg 2d10cf0402 Prepare ChangeLog for upcoming v2.5.0 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-28 19:08:32 +01:00
Joachim Wiberg 7adf2a01f2 Bump version for v2.5.0 release cycle (-dev)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-28 19:07:54 +01:00
Joachim Wiberg a4ff8cce01 strnlen(): defensive programming, check limit before indexing array
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-11-28 16:36:43 +01:00
Joachim Wiberg 12b9196c65 Bump ABI version 5.3.0 -> 5.3.1 according to doc/HACKING.md
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-09 09:21:41 +02:00
Joachim Wiberg 6eee1b1baf doc: update project name
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-09 09:19:49 +02:00
Joachim Wiberg 1a5b184391 debian: add doxygen to Build-Depends-Indep
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-09 09:13:09 +02:00
Joachim Wiberg 832c4a936b Update changelogs and bump version for v2.4.1 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-09 08:57:49 +02:00
Joachim Wiberg a712364d49 tempfile(): use same fallback also when O_TMPFILE is missing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-06 18:05:45 +02:00
Joachim Wiberg fae83c9be3 Use mkostemp() instead of insecure tmpfile() as fallback
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-06 17:51:07 +02:00
Joachim Wiberg 48202ef19e Slightly rearrange and fix URL
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 22:40:11 +02:00
Joachim Wiberg 7c36f715c7 Split README.md in two, create a new doc/API.md
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 22:37:55 +02:00
Joachim Wiberg 328b28f2d1 Restore spacing between badges
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 22:32:08 +02:00
Joachim Wiberg 970fa47ecf Update code docs for string functions and macros as well
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 22:30:20 +02:00
Joachim Wiberg 0a98f5bbd1 Mention API documentation
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 21:34:12 +02:00
Joachim Wiberg 85336b1f2b Link to blog post, to free up GitHub home URL for docs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 21:31:59 +02:00
Joachim Wiberg 8128e63898 Add codedocs status badge
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 21:29:16 +02:00
Joachim Wiberg b52f1e5ad6 debian: drop sdbuf, unused internal variable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 19:14:22 +02:00
Joachim Wiberg 5d1e884d6f Initial codedocs.xyz integration
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 19:10:45 +02:00
Joachim Wiberg 6537b11e34 doc: initial effort to enable doxygen
Framework from libuEv.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 19:08:40 +02:00
Joachim Wiberg 03598fc01e .github: rename test result artifact
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 14:55:42 +02:00
Joachim Wiberg d4649b8284 test: clean up any lingering core file after systemf() test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 13:22:01 +02:00
Joachim Wiberg 3d2a975f11 Fix issue with tempfile() returning EOPNOTSUPP on Azure
Turns out O_TMPFILE can fail in interesting ways when the underlying
filesystem doesn't support unnamed inodes, e.g. Azure used by GitHub
Actions.  Here's the exact qoute from open(2):

  "O_TMPFILE requires support by the underlying filesystem; only a
  subset of Linux filesystems provide that support.  In the initial
  implementation, support was provided in the ext2, ext3, ext4, UDF,
  Minix, and shmem filesystems.  Support for other filesystems has
  subsequently been added as follows: XFS (Linux 3.15); Btrfs (Linux
  3.16); F2FS (Linux 3.16); and ubifs (Linux 4.9)"

This patch adds a silent fallback to tmpfile() in these cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:55:01 +02:00
Joachim Wiberg 1b6707f44e test: investigate why tempfile() fails on debian:stable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:42:16 +02:00
Joachim Wiberg bdebca9681 .github: separate check and distcheck steps, use -j3
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:35:21 +02:00
Joachim Wiberg d364f6b4e1 .github: if debian distcheck fails, show test-suite.log
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:29:52 +02:00
Joachim Wiberg 6db730aeff Bump version for v2.4.1 release cycle (-beta1)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:24:21 +02:00
Joachim Wiberg c512e1cabd .github: prepare initial release general
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:23:23 +02:00
Joachim Wiberg 5d94ca9a14 .github: add coverity scan workflow
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:23:23 +02:00
Joachim Wiberg f0efcb5340 Minor updates and fixes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:23:23 +02:00
Joachim Wiberg 4ee5ca61b8 Drop Travis-CI in favor of GitHub Actions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:48 +02:00
Joachim Wiberg ed491ecdba .github: enable bob
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg b6940814f4 .github: enable funding for this repo
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg 1e91e7ea3f .github: add contributing guidelines
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg 332861430d Minor, cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg 0813084aa7 Import release related fixes to top Makefile from libuEv
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg 990ee6874c Relocate libite.pc.in to src/
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg ef4a8691d3 test: fix build warnings for most tests
Let rsync.c continue to warn, it's not complete ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg 75139cdf3c Relocate lesser used docs to doc/
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg c9633ffbb0 Rename tests/ -> test/ and update internal refs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg 692dbadd3a Prefix CFLAGS/CPPFLAGS/etc with AM_ to prevent env. clashes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:22:33 +02:00
Joachim Wiberg b1a2975a76 Replace obsolete AM_CONFIG_HEADER with AC_CONFIG_HEADERS
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-10-03 12:21:03 +02:00
100 changed files with 5168 additions and 859 deletions

No files matched your search

+193
View File
@@ -0,0 +1,193 @@
# CodeDocs.xyz Configuration File
#
# Rename this example to '.codedocs' and put it in the root directory of your
# repository. This file is optional, documentation will still be generated
# without it using sensible defaults.
#---------------------------------------------------------------------------
# CodeDocs Configuration
#---------------------------------------------------------------------------
# Include the Doxygen configuration from another file.
# The file must be a relative path with respect to the root of the repository.
# If any of the options in this doxyfile include a path (ie, INPUT), these
# paths will be considered relative to the root of the repository, not the
# location of the DOXYFILE.
DOXYFILE = doc/Doxyfile
# Specify external repository to link documentation with.
# This is similar to Doxygen's TAGFILES option, but will automatically link to
# tags of other repositories already using CodeDocs. List each repository to
# link with by giving its location in the form of owner/repository.
# For example:
# TAGLINKS = doxygen/doxygen CodeDocs/osg
# Note: these repositories must already be built on CodeDocs.
TAGLINKS =
#---------------------------------------------------------------------------
# Doxygen Configuration
#---------------------------------------------------------------------------
# Doxygen configuration may also be placed in this file.
# Currently, the following Doxygen configuration options are available. Refer
# to http://doxygen.org/manual/config.html for detailed explanation of the
# options. To request support for more options, contact support@codedocs.xyz.
#
# ABBREVIATE_BRIEF =
# ALIASES =
# ALLEXTERNALS =
# ALLOW_UNICODE_NAMES =
# ALPHABETICAL_INDEX =
# ALWAYS_DETAILED_SEC =
# AUTOLINK_SUPPORT =
# BRIEF_MEMBER_DESC =
# BUILTIN_STL_SUPPORT =
# CALLER_GRAPH =
# CALL_GRAPH =
# CASE_SENSE_NAMES =
# CITE_BIB_FILES =
# CLASS_DIAGRAMS =
# CLASS_GRAPH =
# COLLABORATION_GRAPH =
# COLS_IN_ALPHA_INDEX =
# CPP_CLI_SUPPORT =
# DIAFILE_DIRS =
# DIRECTORY_GRAPH =
# DISABLE_INDEX =
# DISTRIBUTE_GROUP_DOC =
# DOTFILE_DIRS =
# DOT_FONTNAME =
# DOT_FONTSIZE =
# DOT_GRAPH_MAX_NODES =
# DOT_IMAGE_FORMAT =
# DOT_TRANSPARENT =
# DOXYFILE_ENCODING =
# ENABLED_SECTIONS =
# ENABLE_PREPROCESSING =
# ENUM_VALUES_PER_LINE =
# EXAMPLE_PATH =
# EXAMPLE_PATTERNS =
# EXAMPLE_RECURSIVE =
EXCLUDE = src/README.md
# EXCLUDE_PATTERNS =
# EXCLUDE_SYMBOLS =
# EXPAND_AS_DEFINED =
# EXPAND_ONLY_PREDEF =
# EXTENSION_MAPPING =
# EXTERNAL_GROUPS =
# EXTERNAL_PAGES =
# EXTRACT_ALL =
# EXTRACT_ANON_NSPACES =
# EXTRACT_LOCAL_CLASSES =
# EXTRACT_LOCAL_METHODS =
# EXTRACT_PACKAGE =
# EXTRACT_PRIVATE =
# EXTRACT_STATIC =
# EXT_LINKS_IN_WINDOW =
# FILE_PATTERNS =
# FORCE_LOCAL_INCLUDES =
# FORMULA_FONTSIZE =
# FORMULA_TRANSPARENT =
# FULL_PATH_NAMES =
# GENERATE_BUGLIST =
# GENERATE_DEPRECATEDLIST =
# GENERATE_LEGEND =
# GENERATE_TESTLIST =
# GENERATE_TODOLIST =
# GENERATE_TREEVIEW =
# GRAPHICAL_HIERARCHY =
# GROUP_GRAPHS =
# GROUP_NESTED_COMPOUNDS =
# HIDE_COMPOUND_REFERENCE= =
# HIDE_FRIEND_COMPOUNDS =
# HIDE_IN_BODY_DOCS =
# HIDE_SCOPE_NAMES =
# HIDE_UNDOC_CLASSES =
# HIDE_UNDOC_MEMBERS =
# HIDE_UNDOC_RELATIONS =
# HTML_COLORSTYLE_GAMMA =
# HTML_COLORSTYLE_HUE =
# HTML_COLORSTYLE_SAT =
# HTML_DYNAMIC_SECTIONS =
# HTML_EXTRA_FILES =
# HTML_EXTRA_STYLESHEET =
# HTML_FOOTER =
# HTML_HEADER =
# HTML_INDEX_NUM_ENTRIES =
# HTML_STYLESHEET =
# HTML_TIMESTAMP =
# IDL_PROPERTY_SUPPORT =
# IGNORE_PREFIX =
# IMAGE_PATH =
# INCLUDED_BY_GRAPH =
# INCLUDE_FILE_PATTERNS =
# INCLUDE_GRAPH =
# INCLUDE_PATH =
# INHERIT_DOCS =
# INLINE_GROUPED_CLASSES =
# INLINE_INFO =
# INLINE_INHERITED_MEMB =
# INLINE_SIMPLE_STRUCTS =
# INLINE_SOURCES =
INPUT = src/ README.md doc/API.md
# INPUT_ENCODING =
# INTERACTIVE_SVG =
# INTERNAL_DOCS =
# JAVADOC_AUTOBRIEF =
# LAYOUT_FILE =
# MACRO_EXPANSION =
# MARKDOWN_SUPPORT =
# MAX_DOT_GRAPH_DEPTH =
# MSCFILE_DIRS =
# MULTILINE_CPP_IS_BRIEF =
# OPTIMIZE_FOR_FORTRAN =
# OPTIMIZE_OUTPUT_FOR_C =
# OPTIMIZE_OUTPUT_JAVA =
# OPTIMIZE_OUTPUT_VHDL =
# OUTPUT_LANGUAGE =
# PLANTUML_JAR_PATH =
# PREDEFINED =
# PROJECT_BRIEF =
# PROJECT_LOGO =
# PROJECT_NAME =
# PROJECT_NUMBER =
# QT_AUTOBRIEF =
# RECURSIVE =
# REFERENCED_BY_RELATION =
# REFERENCES_LINK_SOURCE =
# REFERENCES_RELATION =
# REPEAT_BRIEF =
# SEARCHENGINE =
# SEARCH_INCLUDES =
# SEPARATE_MEMBER_PAGES =
# SHORT_NAMES =
# SHOW_FILES =
# SHOW_GROUPED_MEMB_INC =
# SHOW_INCLUDE_FILES =
# SHOW_NAMESPACES =
# SHOW_USED_FILES =
# SIP_SUPPORT =
# SKIP_FUNCTION_MACROS =
# SORT_BRIEF_DOCS =
# SORT_BY_SCOPE_NAME =
# SORT_GROUP_NAMES =
# SORT_MEMBERS_CTORS_1ST =
# SORT_MEMBER_DOCS =
# SOURCE_BROWSER =
# SOURCE_TOOLTIPS =
# STRICT_PROTO_MATCHING =
# STRIP_CODE_COMMENTS =
# STRIP_FROM_INC_PATH =
# STRIP_FROM_PATH =
# SUBGROUPING =
# TAB_SIZE =
# TEMPLATE_RELATIONS =
# TREEVIEW_WIDTH =
# TYPEDEF_HIDES_STRUCT =
# UML_LIMIT_NUM_FIELDS =
# UML_LOOK =
USE_MDFILE_AS_MAINPAGE = README.md
# VERBATIM_HEADERS =
#
+90
View File
@@ -0,0 +1,90 @@
Contributing to the Project
===========================
Thank you for considering contributing back to [Free Software][1]!
There are a few things we would like you to consider when filing an
issue or pull request with this project:
1. If you are filing a bug report or feature request
Please take the time to check if an issue already has been filed
matching your problem
2. What version are you running, have you tried the latest release?
UNIX distributions often package and test software for their
particular brand. If you are using a pre-packaged version,
then please file a bug with that distribution instead.
3. Coding Style
Lines are allowed to be longer than 72 characters these days, there
is no enforced max. length.
> **Tip:** Always submit code that follows the style of surrounding code!
The coding style itself is strictly Linux [KNF][], like GIT it is
becoming a de facto standard for C programming
https://www.kernel.org/doc/Documentation/CodingStyle
4. Logical Change Sets
Changes should be broken down into logical units that add a feature
or fix a bug. Keep changes separate from each other and do not mix a
bug fix with a whitespace cleanup or a new feature addition.
This is important not only for readability, or for the possibility of
maintainers to revert changes, but does also increase your chances of
having a change accepted.
5. Commit messages
Commit messages exist to track *why* a change was made. Try to be as
clear and concise as possible in your commit messages, and always, be
proud of your work and set up a proper GIT identity for your commits:
git config --global user.name "J. Random Hacker"
git config --global user.email random.j.hacker@example.com
See this helpful guide for how to write simple, readable commit
messages, or have at least a look at the below example.
http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
Example
-------
Example commit message from the [Pro Git][gitbook] online book, notice
how `git commit -s` is used to automatically add a `Signed-off-by`:
Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug." This convention matches up with commit messages generated
by commands like git merge and git revert.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space, with blank lines in between, but conventions vary here
- Use a hanging indent
Signed-off-by: J. Random Hacker <random.j.hacker@example.com>
[1]: http://www.gnu.org/philosophy/free-sw.en.html
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
[gitbook]: https://git-scm.com/book/ch5-2.html
+3
View File
@@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [troglobit]
+71
View File
@@ -0,0 +1,71 @@
name: Bob the Builder
# Run on all branches, including all pull requests, except the 'dev'
# branch since that's where we run Coverity Scan (limited tokens/day)
on:
push:
branches:
- '**'
- '!dev'
pull_request:
branches:
- '**'
jobs:
build:
# Verify we can build on latest Ubuntu with both gcc and clang
name: ${{ matrix.compiler }}
runs-on: ubuntu-latest
strategy:
matrix:
compiler: [gcc, clang]
fail-fast: false
env:
MAKEFLAGS: -j3
CC: ${{ matrix.compiler }}
steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install tree doxygen
- uses: actions/checkout@v2
- name: Configure
run: |
./autogen.sh
./configure --prefix= --disable-silent-rules
- name: Build
run: |
make
- name: Install to ~/tmp and Inspect
run: |
DESTDIR=~/tmp make install-strip
tree ~/tmp
- name: Run Unit Tests
run: |
make check || (cat test/test-suite.log; false)
- name: Upload Test Results
uses: actions/upload-artifact@v2
with:
name: libite-test-${{ matrix.compiler }}
path: test/*
debian:
name: Verify Debian Package
runs-on: ubuntu-latest
container: debian:stable
env:
MAKEFLAGS: -j3
steps:
- uses: actions/checkout@v2
- name: Installing dependencies
run: |
apt-get update
apt-get install -y build-essential autoconf automake pkg-config doxygen \
dpkg-dev debhelper devscripts
- name: Building Debian package
run: |
./autogen.sh
./configure
make check || (cat test/test-suite.log; false)
make distcheck
make package
cat ../*.changes
+82
View File
@@ -0,0 +1,82 @@
name: Coverity Scan
on:
push:
branches:
- 'dev'
env:
PROJECT_NAME: libite
CONTACT_EMAIL: troglobit@gmail.com
COVERITY_NAME: troglobit-libite
COVERITY_PROJ: troglobit%2Flibite
jobs:
coverity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Fetch latest Coverity Scan MD5
id: var
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${COVERITY_PROJ}&md5=1" \
-O coverity-latest.tar.gz.md5
export MD5=$(cat coverity-latest.tar.gz.md5)
echo "Got MD5 $MD5"
echo ::set-output name=md5::${MD5}
- uses: actions/cache@v2
id: cache
with:
path: coverity-latest.tar.gz
key: ${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
restore-keys: |
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
${{ runner.os }}-coverity-
${{ runner.os }}-coverity
- name: Download Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
if [ ! -f coverity-latest.tar.gz ]; then
wget -q https://scan.coverity.com/download/cxx/linux64 \
--post-data "token=$TOKEN&project=${COVERITY_PROJ}" \
-O coverity-latest.tar.gz
else
echo "Latest Coverity Scan available from cache :-)"
md5sum coverity-latest.tar.gz
fi
mkdir coverity
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config
- name: Configure
run: |
./autogen.sh
./configure --prefix= --disable-silent-rules
- name: Build
run: |
export PATH=`pwd`/coverity/bin:$PATH
cov-build --dir cov-int make
- name: Submit results to Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
run: |
tar czvf ${PROJECT_NAME}.tgz cov-int
curl \
--form project=${COVERITY_NAME} \
--form token=$TOKEN \
--form email=${CONTACT_EMAIL} \
--form file=@${PROJECT_NAME}.tgz \
--form version=trunk \
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
- name: Upload build.log
uses: actions/upload-artifact@v2
with:
name: coverity-build.log
path: cov-int/build-log.txt
+62
View File
@@ -0,0 +1,62 @@
name: Release General
on:
push:
tags:
- 'v*'
jobs:
release:
name: Create GitHub release
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
release_id: ${{ steps.create_release.outputs.id }}
steps:
- uses: actions/checkout@v2
- name: Extract ChangeLog entry ...
# Hack to extract latest entry for body_path below
run: |
awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \
|head -n -1 > release.md
cat release.md
- name: Create release ...
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Libite (-lite) ${{ github.ref }}
body_path: release.md
draft: false
prerelease: false
tarball:
name: Build and upload release tarball
needs: release
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Installing dependencies ...
run: |
sudo apt-get -y update
sudo apt-get -y install tree doxygen
- name: Creating Makefiles ...
run: |
./autogen.sh
./configure
- name: Build release ...
run: |
make release || (cat test/test-suite.log; false)
ls -lF ../
mkdir -p artifacts/
mv ../*.tar.* artifacts/
- name: Upload release artifacts ...
uses: skx/github-action-publish-binaries@release-0.15
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
releaseId: ${{ needs.release.outputs.release_id }}
args: artifacts/*
-39
View File
@@ -1,39 +0,0 @@
# Travis CI integration -- https://travis-ci.org/troglobit/libite
# Defaults to GNU GCC and autotools: ./configure && make && make test
language: c
# Use docker for quicker builds, it now allows https://docs.travis-ci.com/user/apt/
sudo: false
# Test build with both GCC and Clang (LLVM)
compiler:
- gcc
- clang
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "EcWeDUONZnl7IHBWD2rc92LwTWGIlqBZ7wQrLfe3mFXOnB+IZjJIBnDsJDnHDWwA8fGF9NaJbRz4BThroafueUwkDXNyvph1Mdaxm6mdMPyjNJ4H1AFkd9Fz0LYdLNXCPl43tm6s1BR6OWts17lWF6sMnMmIu8gUgXJVg2qsDBl3O9eCoRvQ/h4elLfXZ03fHi4XzzzQvZVyDCg8MCzXIgHJzdkv4llpiCLWQExFbIAVy39euDnx+UuWYB7WDdUbOc7HkkUwf0/vX9PhKVQFKOkXn1ddN0iCsWRH3ti5KXWrBeRO3RPu6Z5YtR8l1WK7iqCYOLuMBW23tXsBQsIW09f1+fFgJ8Ig5hHRRbDinbTUb+mHUJZmNv9ZTc3hPYH4Fyev/ljk42VVDdIBy9AqO42jj8VGmDmiIq47aqNJZUGYZgQlGXGqk9MtavJrqEVcFSgyfEtI+c4n4fzvMRpcEwjnbp482s1xNzHQZ1GQI77Td5UUXXWyNSCoQoE/VpkAesYJAw8KwXOXveDr3Qu0HhuQu1oyLmWHlZHYDu+TInjY81gpGw9Cm7/SdFoA0Ag49PlAXdPRymbP01B50MqrCTxtXEHtdXxhrkDvaoUp7heSuvO0fS+mI5F7eQ4Ji2JdyRSt1KpXVNAyL1FrO/yznM3EwcXPmWmrc+QjFtC9vY4="
before_install:
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
addons:
coverity_scan:
project:
name: "troglobit/libite"
description: "That missing frog DNA you've been looking for"
notification_email: troglobit@gmail.com
build_command_prepend: "./autogen.sh && ./configure --prefix= --disable-silent-rules"
build_command: "make clean all"
branch_pattern: dev
script:
- ./autogen.sh
- ./configure --prefix= --disable-silent-rules
- make clean
- make -j5
- make install-strip DESTDIR=/tmp/foo
- ls -lR /tmp/foo
- make distcheck
+43 -1
View File
@@ -4,6 +4,46 @@ Change Log
All notable changes to the project are documented in this file.
[v2.5.0][] - 2021-11-30
-----------------------
> **Note:** namespace change; the -lite library include files have moved
> from `lite/*.h` to `libite/*.h` due to an unfortunate clash
> with "LiTE is a Toobox Engine", from the DirectFB project.
> For a transitional period, however, a compatibility symlink
> is installed; `lite -> libite/`.
### Changes
- Header files have moved from `lite/*.h` to `libite/*.h` to prevent
clashing with DirectFB LiTE library.
- Include guards in header files have been renamed, much in the same
fashion as the move (above), from `LITE_foo_H_` to `LIBITE_FOO_H_`
- Add configure option to disable compatibility symlink, for systems
that do not want name clashes with DirectFB/LiTE, or do not need to
be backwards compatible; use `configure --without-symlink`
### Fixes
- Minor, use defensive coding in `strnlen()` replacement. Only used
on systems that do not have a native implementation.
[v2.4.1][] - 2021-10-09
-----------------------
### Changes
- Add doxygen API documentation to project, included in tarball, and
automatically generated at https://codedocs.xyz/troglobit/libite/
- Relocate `tests/` to `test/` in source tree
- Relocate `docs/` to `doc/` in source tree
### Fixes
- Prefix CFLAGS/CPPFLAGS/etc with `AM_` in `test/Makefile.am` to prevent
clashing with environment. Fix imported from libuEv
- Replace obsolete `AM_CONFIG_HEADER` with `AC_CONFIG_HEADERS`
- Fix issue with `tempfile()` returning EOPNOTSUPP on Azure, use
fallback to `mkostemp()` with `O_CLOEXEC` flag set
[v2.4.0][] - 2021-03-27
-----------------------
@@ -413,7 +453,9 @@ problems this may cause!
Initial extraction of frog DNA from [Finit][]. See [README][] for API details.
[UNRELEASED]: https://github.com/troglobit/libite/compare/v2.4.0...HEAD
[UNRELEASED]: https://github.com/troglobit/libite/compare/v2.4.1...HEAD
[v2.5.0]: https://github.com/troglobit/libite/compare/v2.4.1...v2.5.0
[v2.4.1]: https://github.com/troglobit/libite/compare/v2.4.0...v2.4.1
[v2.4.0]: https://github.com/troglobit/libite/compare/v2.3.1...v2.4.0
[v2.3.1]: https://github.com/troglobit/libite/compare/v2.3.0...v2.3.1
[v2.3.0]: https://github.com/troglobit/libite/compare/v2.2.1...v2.3.0
+16 -6
View File
@@ -1,14 +1,24 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src test
doc_DATA = README.md LICENSE ChangeLog.md
EXTRA_DIST = README.md LICENSE ChangeLog.md
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libite.pc
SUBDIRS = src tests
if ENABLE_DOXYGEN
SUBDIRS += doc
.PHONY: doc
doc:
$(MAKE) -C @top_builddir@/doc $@
## The distribution should include man pages, which are generated
dist-hook: doc
else
doc:
@echo "Doxygen documentation (html + man) disabled, skipping ..."
endif
## Check if tagged in git
release-hook:
@if [ ! `git tag | grep $(PACKAGE_VERSION)` ]; then \
@if [ ! `git tag -l v$(PACKAGE_VERSION) | grep $(PACKAGE_VERSION)` ]; then \
echo; \
printf "\e[1m\e[41mCannot find release tag $(PACKAGE_VERSION)\e[0m\n"; \
printf "\e[1m\e[5mDo release anyway?\e[0m "; read yorn; \
@@ -29,7 +39,7 @@ package:
@debuild -uc -us -B --lintian-opts --profile debian -i -I --show-overrides
## Target to run when building a release
release: release-hook distcheck package
release: release-hook distcheck
@for file in $(DIST_ARCHIVES); do \
md5sum $$file > ../$$file.md5; \
sha256sum $$file > ../$$file.sha256; \
+78 -412
View File
@@ -1,16 +1,19 @@
-lite | Frog DNA, basically
===========================
[![Travis Status][]][Travis] [![Coverity Status]][Coverity Scan]
[![GitHub Status][]][GitHub] [![codedocs status][]][codedocs] [![Coverity Status][]][Coverity Scan]
Table of Contents
-----------------
* [Introduction](#introduction)
* [Using -lite](#using--lite)
* [Helper Macros](#helper-macros)
* [Generic Functions](#generic-functions)
* [OpenBSD Functions](#openbsd-functions)
* [Build & Install](#origin--references)
* [API](doc/API.md#overview)
* [Important Node](doc/API.md#important-note)
* [Helper Macros](doc/API.md#helper-macros)
* [Generic Functions](doc/API.md#generic-functions)
* [GNU Functions](doc/API.md#gnu-functions)
* [OpenBSD/NetBSD/FreeBSD Functions](doc/API.md#openbsd-netbsd-freebsd-functions)
* [Build & Install](#build--install)
* [Origin & References](#origin--references)
@@ -33,411 +36,65 @@ recommended when traversing lists to delete/free nodes.
The code is open sourced under a mix of permissive Open Source licenses:
[MIT/X11 license][MIT], [ISC license][ISC], and [BSD licenses][BSD].
> **Tip:** have a look at my blog post about other useful UNIX API's!
> https://troglobit.com/post/2020-02-22-useful-unix-apis/
Using -lite
-----------
Libite is by default installed as a library and a set of include files.
To prevent clashing with include files of the same name `-lite` employs
an include file namespace `lite/`, which is strongly recommended to use
in your applications:
an include file namespace `libite/`, which is strongly recommended to
use in your applications:
#include <lite/lite.h>
#include <lite/conio.h>
#include <lite/queue.h>
#include <lite/tree.h>
```C
#include <libite/lite.h>
#include <libite/conio.h>
#include <libite/queue.h>
#include <libite/tree.h>
```
The output from the `pkg-config` tool holds no surprises in this regard:
> **Note:** prior to v2.5.0, the `lite/` namespace was used for headers,
> which is still available in the default install. This clashed with
> the headers of the LiTE library from the DirectFB project.
$ pkg-config --libs --static --cflags libite
-I/usr/local/include -L/usr/local/lib -lite
The output from the `pkg-config` tool holds no surprises:
```bash
$ pkg-config --libs --static --cflags libite
-I/usr/local/include -D_LIBITE_LITE -L/usr/local/lib -lite
```
> **Note:** `_LIBITE_LITE` is defined since v2.5.0, useful for software
> that want to be able to build against headers from an older libite:
>
> ```C
> #ifdef _LIBITE_LITE
> # include <libite/lite.h>
> #else
> # include <lite/lite.h>
> #endif
> ```
The prefix path `/usr/local/` shown here is only the default. Use the
`configure` script to select a different prefix when installing libite.
For GNU autotools based projects, use the following in `configure.ac`:
# Check for required libraries
PKG_CHECK_MODULES([lite], [libite >= 1.5.0])
```m4
# Check for required libraries
PKG_CHECK_MODULES([lite], [libite >= 1.5.0])
```
and in your `Makefile.am`:
proggy_CFLAGS = $(lite_CFLAGS)
proggy_LDADD = $(lite_LIBS)
```Makefile
proggy_CFLAGS = $(lite_CFLAGS)
proggy_LDADD = $(lite_LIBS)
```
Important Note
--------------
When using functions like `mkpath()`, `makepath()`, and `makefifo()`,
make sure your `umask()` is correct so you do not accidentally create
files and directories accessible to other users than intended.
Helper Macros
-------------
- `atonum(str)`
Convert string to natural number, works for 32-bit non-negative
integers. Returns -1 on error. (Uses `strtonum()` internally.)
- `blkdev(dev)`
Create block device
- `chardev(dev)`
Create character device
- `erase(path)`
Erase file/directory with `remove()`. Errors on `stderr`
- `erasef(fmt, ...)`
Like `erase()` but takes a formatted printf-like string as argument.
- `makedir(path)`
Create directory, like `mkdir()`. Errors on `stderr`
- `makefifo(path)`
Create a FIFO, like `mkfifo()`. Errors on `stderr`
- `min(a,b)`/`max(a,b)`
These macros take care to avoid double evaluation.
- `touch(path)`
Create a file, or update mtime. Errors on `stderr`
- `touchf(fmt, ...)`
Like `touch()` but takes a formatted printf-like string as argument.
- `S_ISEXEC(mode_t m)`
Mysteriously missing from GLIBC
- `ISCLR(word,bit)`
Is bit in (integer) word cleared?
- `ISSET(word,bit)`
Is bit in (integer) word set?
- `ISOTHER(word,bit)`
Are any other bits, except bit, in (integer) word set?
- `SETBIT(word,bit)`
Set bit in (integer) word.
- `CLRBIT(word,bit)`
Clear bit in (integer) word.
- `NELEMS(array)`
Returns the number of elements in an array. From the great book, The
Practice of Programming, by Kernighan and Pike.
Generic Functions
-----------------
- `chomp(str)`
Perl like chomp function, chop off last char if newline.
- `copyfile(src, dst, len, opt)`
Like the shell `cp(1)` and `dd(1),`, can also copy symlinks and
preserve the mtime of the source file. The opt argument can be
a mask of:
- `LITE_FOPT_COPYFILE_SYM (0x01)`
- `LITE_FOPT_KEEP_MTIME (0x02)`
In releases prior to v2.0 the opt argument was called `symlink`.
The APIs are 100% compatible if the value `1` was used to enable
the symlink option.
- `dir(dir, ext, filter, list, strip)`
Wrapper for `scandir()` with optional filter. Returns a list of
names: files and directories that must be freed after use. See
the unit test for an example, or take a look at `glob(3)`, it's
probably what you want anyway.
- `fcopyfile(src, dst)`
Like `copyfile()` but uses already open `FILE *` pointers. Copies
from current file positions to current file positions until EOF.
- `fexist(file)`
Check for the existence of a file, returns True(1) or False(0).
- `fisdir(path)`
Check for the existence of a directory, returns True(1) or False(0).
- `fopenf(mode, fmt, ...)`
Like `fopen()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
filename from parts into a dynamic buffer before actually opening
the file.
> **Notice:** the swapped order of `pathname` and `mode`!
- `fremove(fmt, ...)`
Like `remove()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
filename from parts into a dynamic buffer before actually removing
the file.
- `fsendfile(src, dst, len)`
Copy data between file streams, very similar to `fcopyfile()`, but
`dst` is allowed to be `NULL` to be able to read and discard `len`
bytes from `src`.
- `ifconfig(ifname, addr, mask, up)`
Basic ifconfig like operations on an interface. Only supports IPv4
addresses. Note that mask is not CIDR notation.
- `lfopen(file, sep)`, `lfclose(lf)`
LITE file API for parsing UNIX style configuration files like
`/etc/protocols` and `/etc/services`.
- `lftok(lf)`
Read tokens, delimited by `sep`, from file opened with `lfopen()`.
- `lfgetkey(lf, key)`
Find `key` in file opened with `lfopen()`, return value/argument.
- `lfgetint(lf, key)`
Wrapper for `lfgetkey()`, returns positive integer value to `key`,
or `-1` if `key` is not found.
- `fgetint(file, sep, key)`
Wrapper for `lfopen()`, `lfgetint()`, and `lfclose()`. Useful for
when only reading a single `key` from a file.
- `makepath(dir)`
Create all components of the specified directory.
- `mkpath(dir, mode)`
Like `makepath()`, but also takes a `mode_t` permission mode argument.
- `fmkpath(mode, fmt, ...)`
Like `mkpath()`, but takes a formatted string as argument.
> **Notice:** the swapped order of `pathname` and `mode`!
- `movefile(src, dst)`
Like `copyfile()`, but renames `src` to `dst`, or recreates symlink
with the `dst` name. On successful operation the source is removed
and the function returns POSIX OK (0).
- `pidfile(name)`
Create a daemon PID file using either the `name` as a full path, if
`name` starts with `/`, or in `_PATH_VARRUN` using `name` as the
basename of the application. If `name` is `NULL`, then `__progname`
is used as the basename. The resulting file name is available to the
user as a read-only pointer:
extern char *__pidfile_name;
Use this function to create a PID file for your daemon when it is
ready to receive signals. A client application may poll for the
existence of this file, so make sure to have your signal handlers
properly setup before calling this function.
The PID file is removed when the program exits, using an `atexit()`
handler. However, depending on how the program terminates the file
may still exist even though the program is no longer running.
Calling this function multiple times updates the mtime of the file.
Only one `atexit()` handler is created, regardless of the amount of
times the function is called. If the file is removed, subsequent
calls to this function will recreate the file.
See below for a link to OpenBSD man page.
- `pidfile_read(pidfile)`
Read PID from pid file created by `pidfile()`.
- `pidfile_signal(pidfile, signal)`
Send signal to PID found in pid file created by `pidfile()`.
- `progress(percent, max_width)`
Simple ASCII progress bar with a spinner. Start it with `percent=0`
and set the `max_width=chars` to indicate width of the progress bar.
Called multiple times with the same percentage value cause spinner to
spin.
- `rsync(src, dst, opt, *filter())`
Very simple `rsync()` to copy files and directories recursively. It
supports pruning files from the destination tree that do not exist in
the source tree and preserving the mtime of the source files. The opt
argument can be a mask of:
- `LITE_FOPT_RSYNC_DELETE (0x01)`
- `LITE_FOPT_KEEP_MTIME (0x02)`
In releases prior to v2.0 the argument controlling pruning was called
`delete`, it is now called `opt`. The APIs are 100% compatible if the
value `1` was used.
- `strmatch(str, list)`, `strnmatch(str, list, len)`
Find matching string in an array of strings. Returns index in array on
match, or `-1` on error or not found. `strnmatch()` takes an extra arg
to compare only `len` number of characters from `str`.
- `strtrim(str)`
Trims a string from any leading and trailing white-space, returns the
trimmed result in the same buffer.
- `systemf(fmt, ...)`
Like `system()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
command from parts into a dynamic buffer before calling it.
- `telnet_open(addr, port), telnet_close(ctx), telnet_expect(ctx, script, output)`
Poor mans telnet expect in C. Opens connection to a Telnet service;
FTP, Telnet, similar, and run an expect-like script.
- `telnet_session(addr, port, script output)`
Wrapper for the above three in one API.
- `tempfile()`
Secure replacement for `tmpfile()`. Creates an invisible temporary
file in `/tmp` that is removed when the returned `FILE` pointer is
closed.
**Note:** Requires Linux v3.11, or later, will fall back to the old
and unsafe `tmpfile()` on older systems.
- `truncatef(length, fmt, ...)`
Like `truncate()`, but takes a formatted string as argument. This
simplifies some operations when the filename otherwise have to be
composed from parts into a separate array before calling the real
function.
- `which(cmd)`, `whichp(cmd)`
C implementation of UNIX which(1). Returns a malloc'ed string with the
full path to `cmd` on success, otherwise `NULL`.
`whichp()` is a predicate function, returns `TRUE` or `FALSE`.
**Note:** `which("/bin/ps aux")` will return `/bin/ps`, or `TRUE`,
provided of course `/bin/ps` exists.
- `yorn(fmt, ...)`
Pose a question to user, appended with `(y/N)?`, returns `TRUE` for
yes (both `y` and `Y` are handled) and `FALSE` for everything else.
GNU Functions
-------------
The following are useful GNU functions, that do not exist on *BSD, and
some other platforms.
- `strdupa(str)`
http://man7.org/linux/man-pages/man3/strdupa.3.html
- `strndupa(str)`
http://man7.org/linux/man-pages/man3/strndupa.3.html
- `strnlen(str, lim)`
http://man7.org/linux/man-pages/man3/strnlen.3.html
OpenBSD/NetBSD/FreeBSD Functions
--------------------------------
The following are popular functions and highly useful macros from the
*BSD world of UNIX that are sadly missing on Linux.
- `fparseln(fp, *len, *lineno, delim, flags)`
http://man.openbsd.org/OpenBSD-current/man3/fparseln.3
- `pidfile(basename)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/pidfile.3
**Note:** the version of `pidfile()` in -lite has been extended to
handle it being called multiple times, i.e. to not create multiple
`atexit()` handlers, and also to export a few internal paths:
- `__pidfile_path`: prefix path, default `_PATH_VARRUN`. Notice the
trailing slash requirement if you want to override it!
- `__pidfile_name`: full path to PID file , similar to `__progname`.
See previous section for details.
- `reallocarray(ptr, nmemb, size)`
http://man.openbsd.org/OpenBSD-current/man3/reallocarray.3
- `strlcpy(dst, src, len)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strlcpy.3
- `strlcat(dst, src, len)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strlcat.3
- `strtonum()`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strtonum.3
- `sys/queue.h` API
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/LIST_EMPTY.3
- `sys/tree.h` API
Niels Provos' famous splay and red-black tree implementation.
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/SPLAY_FOREACH.3
> API Documentaion: https://codedocs.xyz/troglobit/libite/
Build & Install
@@ -446,10 +103,18 @@ Build & Install
This library was initially built for and developed on GNU/Linux systems
as a light weight utility library, these days NetBSD should also work.
./configure
make -j5
sudo make install-strip
sudo ldconfig
```bash
$ ./configure
$ make -j5
$ sudo make install-strip
$ sudo ldconfig
```
Use <kbd>./configure --without-symlink</kbd> to prevent the install step
from creating the `lite -> libite/` compatibility symlink for the header
files, required for systems with DirectFB LiTE. The default, however,
is to install the symlink to ensure compatibility with existing software
that depends on the `-lite` library headers in their previous namespace.
**Note:** When checking out code from GIT, use <kbd>./autogen.sh</kbd>
to generate a `configure` script. It is a generated file and otherwise
@@ -460,24 +125,25 @@ Origin & References
-------------------
Much of the code in libite (-lite) is written by [Claudio Matsuoka][]
for [Finit][original finit] and released under the MIT/X11 license.
Joachim Wiberg later improved on the [Finit][] code base and included
pieces of software released under the ISC and BSD licenses. See each
respective file for license details.
for the original [Finit][original finit] and released under the MIT/X11
license. Joachim Wiberg later improved on the [Finit][1] code base and
included pieces of software released under the ISC and BSD licenses.
See each respective file for license details.
[1]: https://github.com/troglobit/finit
[2]: http://www.openbsd.org/
[3]: http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
[4]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/LIST_EMPTY.3
[5]: https://developer.gnome.org/glib/
[7]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/SPLAY_FOREACH.3
[MIT]: https://en.wikipedia.org/wiki/MIT_License
[ISC]: https://en.wikipedia.org/wiki/ISC_license
[BSD]: https://en.wikipedia.org/wiki/BSD_licenses
[Travis]: https://travis-ci.org/troglobit/libite
[Travis Status]: https://travis-ci.org/troglobit/libite.svg?branch=master
[1]: https://github.com/troglobit/finit
[2]: http://www.openbsd.org/
[3]: http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
[4]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/LIST_EMPTY.3
[5]: https://developer.gnome.org/glib/
[7]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/SPLAY_FOREACH.3
[MIT]: https://en.wikipedia.org/wiki/MIT_License
[ISC]: https://en.wikipedia.org/wiki/ISC_license
[BSD]: https://en.wikipedia.org/wiki/BSD_licenses
[GitHub]: https://github.com/troglobit/libite/actions/workflows/build.yml/
[GitHub Status]: https://github.com/troglobit/libite/actions/workflows/build.yml/badge.svg
[Coverity Scan]: https://scan.coverity.com/projects/20602
[Coverity Status]: https://img.shields.io/coverity/scan/20602.svg
[codedocs]: https://codedocs.xyz/troglobit/libite.log
[codedocs status]: https://codedocs.xyz/troglobit/libite.svg
[Claudio Matsuoka]: https://github.com/cmatsuoka
[original finit]: http://helllabs.org/finit/
[Finit]: https://github.com/troglobit/finit
[original finit]: http://helllabs.org/finit/
+26 -3
View File
@@ -1,11 +1,11 @@
AC_INIT(libite, 2.4.0, https://github.com/troglobit/libite/issues)
AC_INIT(libite, 2.5.0, https://github.com/troglobit/libite/issues)
AC_CONFIG_AUX_DIR(aux)
AM_INIT_AUTOMAKE([1.11 foreign dist-xz])
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/lite.h)
AM_CONFIG_HEADER(config.h)
AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile libite.pc])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_FILES([Makefile doc/Makefile doc/Doxyfile src/Makefile src/libite.pc test/Makefile])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_CC
@@ -13,4 +13,27 @@ AC_PROG_INSTALL
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
LT_INIT
# Check for Doxygen and enable its features.
# For details, see m4/ax_prog_doxygen.m4 and
# http://www.bioinf.uni-freiburg.de/~mmann/HowTo/automake.html#doxygenSupport
DX_DOXYGEN_FEATURE(ON)
DX_DOT_FEATURE(OFF)
DX_CHI_FEATURE(OFF)
DX_RTF_FEATURE(OFF)
DX_XML_FEATURE(OFF)
DX_PDF_FEATURE(OFF)
DX_PS_FEATURE(OFF)
DX_CHM_FEATURE(OFF)
DX_HTML_FEATURE(ON)
DX_MAN_FEATURE(OFF)
DX_INIT_DOXYGEN(${PACKAGE_NAME}, [${top_builddir}/doc/Doxyfile], [${top_builddir}/doc])
AC_ARG_WITH([symlink],
AS_HELP_STRING([--without-symlink], [Disable compat /usr/include/lite -> libite symlink]),,
[with_symlink=yes])
AM_CONDITIONAL([ENABLE_DOXYGEN], [test "x${DX_FLAG_doc}" = x1])
AM_CONDITIONAL([ENABLE_HTML], [test "x${DX_FLAG_html}" = x1])
AM_CONDITIONAL([COMPAT_SYMLINK], [test "x$with_symlink" != "xno"])
AC_OUTPUT
+16
View File
@@ -1,3 +1,19 @@
libite (2.5.0) stable; urgency=medium
* Header files have moved from `lite/*.h` to `libite/*.h` to prevent
clashing with DirectFB LiTE library. For a transitional period,
however, a compatibility symlink is installed; `lite -> libite/`.
-- Joachim Wiberg <troglobit@gmail.com> Tue, 30 Nov 2021 06:57:17 +0100
libite (2.4.1) stable; urgency=medium
* Add doxygen documentation, https://codedocs.xyz/troglobit/libite/
* Fix issue with tempfile() returning EOPNOTSUP on certain file systems,
added fallback that uses mkstemp() with O_CLOEXEC flag set
-- Joachim Wiberg <troglobit@gmail.com> Sat, 09 Oct 2021 08:56:43 +0200
libite (2.4.0) stable; urgency=medium
* New functions:
+4 -3
View File
@@ -1,12 +1,13 @@
Source: libite
Section: libs
Priority: optional
Maintainer: Joachim Wiberg <troglobit@gmail.com>
Build-Depends: debhelper (>= 10), libtool
Build-Depends: debhelper (>= 10)
Build-Depends-Indep: doxygen
Standards-Version: 4.3.0
Section: libs
Homepage: https://github.com/troglobit/libite/
Vcs-Git: https://github.com/troglobit/libite.git
Vcs-Browser: https://github.com/troglobit/libite/
Vcs-Git: https://github.com/troglobit/libite.git
Package: libite-dev
Priority: optional
+1 -1
View File
@@ -124,5 +124,5 @@ Files: yorn.c
Copyright: 2009-2021 Joachim Wiberg <troglobit@gmail.com>
License: ISC
Files: tests/*.c
Files: test/*.c
License: public-domain
+2 -1
View File
@@ -1,4 +1,5 @@
usr/include/lite/*.h
usr/include/libite/*.h
usr/include/lite
usr/lib/*/lib*.a
usr/lib/*/lib*.so
usr/lib/*/pkgconfig/lib*.pc
-1
View File
@@ -33,7 +33,6 @@ libite.so.5 libite5 #MINVER#
progress_simple@Base 2.0.0
reallocarray@Base 2.0.0
rsync@Base 2.0.0
sdbuf@Base 2.0.0
strlcat@Base 2.0.0
strlcpy@Base 2.0.0
strmatch@Base 2.1.0
+3
View File
@@ -0,0 +1,3 @@
html/*
libite.tag
Doxyfile
+376
View File
@@ -0,0 +1,376 @@
API Documentation
=================
Important Note
--------------
When using functions like `mkpath()`, `makepath()`, and `makefifo()`,
make sure your `umask()` is correct so you do not accidentally create
files and directories accessible to other users than intended.
Helper Macros
-------------
- `atonum(str)`
Convert string to natural number, works for 32-bit non-negative
integers. Returns -1 on error. (Uses `strtonum()` internally.)
- `blkdev(dev)`
Create block device
- `chardev(dev)`
Create character device
- `erase(path)`
Erase file/directory with `remove()`. Errors on `stderr`
- `erasef(fmt, ...)`
Like `erase()` but takes a formatted printf-like string as argument.
- `makedir(path)`
Create directory, like `mkdir()`. Errors on `stderr`
- `makefifo(path)`
Create a FIFO, like `mkfifo()`. Errors on `stderr`
- `min(a,b)`/`max(a,b)`
These macros take care to avoid double evaluation.
- `touch(path)`
Create a file, or update mtime. Errors on `stderr`
- `touchf(fmt, ...)`
Like `touch()` but takes a formatted printf-like string as argument.
- `S_ISEXEC(mode_t m)`
Mysteriously missing from GLIBC
- `ISCLR(word,bit)`
Is bit in (integer) word cleared?
- `ISSET(word,bit)`
Is bit in (integer) word set?
- `ISOTHER(word,bit)`
Are any other bits, except bit, in (integer) word set?
- `SETBIT(word,bit)`
Set bit in (integer) word.
- `CLRBIT(word,bit)`
Clear bit in (integer) word.
- `NELEMS(array)`
Returns the number of elements in an array. From the great book, The
Practice of Programming, by Kernighan and Pike.
Generic Functions
-----------------
- `chomp(str)`
Perl like chomp function, chop off last char if newline.
- `copyfile(src, dst, len, opt)`
Like the shell `cp(1)` and `dd(1),`, can also copy symlinks and
preserve the mtime of the source file. The opt argument can be
a mask of:
- `LITE_FOPT_COPYFILE_SYM (0x01)`
- `LITE_FOPT_KEEP_MTIME (0x02)`
In releases prior to v2.0 the opt argument was called `symlink`.
The APIs are 100% compatible if the value `1` was used to enable
the symlink option.
- `dir(dir, ext, filter, list, strip)`
Wrapper for `scandir()` with optional filter. Returns a list of
names: files and directories that must be freed after use. See
the unit test for an example, or take a look at `glob(3)`, it's
probably what you want anyway.
- `fcopyfile(src, dst)`
Like `copyfile()` but uses already open `FILE *` pointers. Copies
from current file positions to current file positions until EOF.
- `fexist(file)`
Check for the existence of a file, returns True(1) or False(0).
- `fisdir(path)`
Check for the existence of a directory, returns True(1) or False(0).
- `fopenf(mode, fmt, ...)`
Like `fopen()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
filename from parts into a dynamic buffer before actually opening
the file.
> **Notice:** the swapped order of `pathname` and `mode`!
- `fremove(fmt, ...)`
Like `remove()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
filename from parts into a dynamic buffer before actually removing
the file.
- `fsendfile(src, dst, len)`
Copy data between file streams, very similar to `fcopyfile()`, but
`dst` is allowed to be `NULL` to be able to read and discard `len`
bytes from `src`.
- `ifconfig(ifname, addr, mask, up)`
Basic ifconfig like operations on an interface. Only supports IPv4
addresses. Note that mask is not CIDR notation.
- `lfopen(file, sep)`, `lfclose(lf)`
LITE file API for parsing UNIX style configuration files like
`/etc/protocols` and `/etc/services`.
- `lftok(lf)`
Read tokens, delimited by `sep`, from file opened with `lfopen()`.
- `lfgetkey(lf, key)`
Find `key` in file opened with `lfopen()`, return value/argument.
- `lfgetint(lf, key)`
Wrapper for `lfgetkey()`, returns positive integer value to `key`,
or `-1` if `key` is not found.
- `fgetint(file, sep, key)`
Wrapper for `lfopen()`, `lfgetint()`, and `lfclose()`. Useful for
when only reading a single `key` from a file.
- `makepath(dir)`
Create all components of the specified directory.
- `mkpath(dir, mode)`
Like `makepath()`, but also takes a `mode_t` permission mode argument.
- `fmkpath(mode, fmt, ...)`
Like `mkpath()`, but takes a formatted string as argument.
> **Notice:** the swapped order of `pathname` and `mode`!
- `movefile(src, dst)`
Like `copyfile()`, but renames `src` to `dst`, or recreates symlink
with the `dst` name. On successful operation the source is removed
and the function returns POSIX OK (0).
- `pidfile(name)`
Create a daemon PID file using either the `name` as a full path, if
`name` starts with `/`, or in `_PATH_VARRUN` using `name` as the
basename of the application. If `name` is `NULL`, then `__progname`
is used as the basename. The resulting file name is available to the
user as a read-only pointer:
extern char *__pidfile_name;
Use this function to create a PID file for your daemon when it is
ready to receive signals. A client application may poll for the
existence of this file, so make sure to have your signal handlers
properly setup before calling this function.
The PID file is removed when the program exits, using an `atexit()`
handler. However, depending on how the program terminates the file
may still exist even though the program is no longer running.
Calling this function multiple times updates the mtime of the file.
Only one `atexit()` handler is created, regardless of the amount of
times the function is called. If the file is removed, subsequent
calls to this function will recreate the file.
See below for a link to OpenBSD man page.
- `pidfile_read(pidfile)`
Read PID from pid file created by `pidfile()`.
- `pidfile_signal(pidfile, signal)`
Send signal to PID found in pid file created by `pidfile()`.
- `progress(percent, max_width)`
Simple ASCII progress bar with a spinner. Start it with `percent=0`
and set the `max_width=chars` to indicate width of the progress bar.
Called multiple times with the same percentage value cause spinner to
spin.
- `rsync(src, dst, opt, *filter())`
Very simple `rsync()` to copy files and directories recursively. It
supports pruning files from the destination tree that do not exist in
the source tree and preserving the mtime of the source files. The opt
argument can be a mask of:
- `LITE_FOPT_RSYNC_DELETE (0x01)`
- `LITE_FOPT_KEEP_MTIME (0x02)`
In releases prior to v2.0 the argument controlling pruning was called
`delete`, it is now called `opt`. The APIs are 100% compatible if the
value `1` was used.
- `strmatch(str, list)`, `strnmatch(str, list, len)`
Find matching string in an array of strings. Returns index in array on
match, or `-1` on error or not found. `strnmatch()` takes an extra arg
to compare only `len` number of characters from `str`.
- `strtrim(str)`
Trims a string from any leading and trailing white-space, returns the
trimmed result in the same buffer.
- `systemf(fmt, ...)`
Like `system()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
command from parts into a dynamic buffer before calling it.
- `telnet_open(addr, port), telnet_close(ctx), telnet_expect(ctx, script, output)`
Poor mans telnet expect in C. Opens connection to a Telnet service;
FTP, Telnet, similar, and run an expect-like script.
- `telnet_session(addr, port, script output)`
Wrapper for the above three in one API.
- `tempfile()`
Secure replacement for `tmpfile()`. Creates an invisible temporary
file in `/tmp` that is removed when the returned `FILE` pointer is
closed.
**Note:** Requires Linux v3.11, or later, will fall back to the old
and unsafe `tmpfile()` on older systems.
- `truncatef(length, fmt, ...)`
Like `truncate()`, but takes a formatted string as argument. This
simplifies some operations when the filename otherwise have to be
composed from parts into a separate array before calling the real
function.
- `which(cmd)`, `whichp(cmd)`
C implementation of UNIX which(1). Returns a malloc'ed string with the
full path to `cmd` on success, otherwise `NULL`.
`whichp()` is a predicate function, returns `TRUE` or `FALSE`.
**Note:** `which("/bin/ps aux")` will return `/bin/ps`, or `TRUE`,
provided of course `/bin/ps` exists.
- `yorn(fmt, ...)`
Pose a question to user, appended with `(y/N)?`, returns `TRUE` for
yes (both `y` and `Y` are handled) and `FALSE` for everything else.
GNU Functions
-------------
The following are useful GNU functions, that do not exist on *BSD, and
some other platforms.
- `strdupa(str)`
http://man7.org/linux/man-pages/man3/strdupa.3.html
- `strndupa(str)`
http://man7.org/linux/man-pages/man3/strndupa.3.html
- `strnlen(str, lim)`
http://man7.org/linux/man-pages/man3/strnlen.3.html
OpenBSD/NetBSD/FreeBSD Functions
--------------------------------
The following are popular functions and highly useful macros from the
*BSD world of UNIX that are sadly missing on Linux.
- `fparseln(fp, *len, *lineno, delim, flags)`
http://man.openbsd.org/OpenBSD-current/man3/fparseln.3
- `pidfile(basename)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/pidfile.3
**Note:** the version of `pidfile()` in -lite has been extended to
handle it being called multiple times, i.e. to not create multiple
`atexit()` handlers, and also to export a few internal paths:
- `__pidfile_path`: prefix path, default `_PATH_VARRUN`. Notice the
trailing slash requirement if you want to override it!
- `__pidfile_name`: full path to PID file , similar to `__progname`.
See previous section for details.
- `reallocarray(ptr, nmemb, size)`
http://man.openbsd.org/OpenBSD-current/man3/reallocarray.3
- `strlcpy(dst, src, len)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strlcpy.3
- `strlcat(dst, src, len)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strlcat.3
- `strtonum()`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strtonum.3
- `sys/queue.h` API
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/LIST_EMPTY.3
- `sys/tree.h` API
Niels Provos' famous splay and red-black tree implementation.
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/SPLAY_FOREACH.3
+2579
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -71,13 +71,13 @@ disable your brain and follow the rules, one by one.
have changed. The initial version is 1:0:0, we follow the rules above to
the letter: increase revision, increase current and set revision to zero,
and finally increase age. This, rather confusingly, gives us 2:0:1 which
libtool then translates to `libconfuse.so.1.1.0`.
libtool then translates to `libite.so.1.1.0`.
**Example #2:** some existing functions are changed, they now return an
`int` instead of `void`. The initial version is 0:0:0, and we follow the
rules again: increment revision, increment current and set revision to
zero, set age to zero. This gives us 1:0:0, which is then translated to
`libconfuse.so.1.0.0`.
`libite.so.1.0.0`.
### Note
+22
View File
@@ -0,0 +1,22 @@
dist_doc_DATA = API.md
EXTRA_DIST = API.md Doxyfile.in
DISTCLEANFILES = libite.tag
if ENABLE_HTML
pkghtmldir = $(docdir)/html
pkghtml_DATA = html/*
#
# Doxygen rules from m4/ax_prog_doxygen.m4
#
@DX_RULES@
$(pkghtml_DATA): doxygen-doc
all-local: doc
clean-local:
-rm -rf html libite.tag
doc: doxygen-doc
endif
View File
File renamed without changes.
+585
View File
@@ -0,0 +1,585 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
# ===========================================================================
#
# SYNOPSIS
#
# DX_INIT_DOXYGEN(PROJECT-NAME, [DOXYFILE-PATH], [OUTPUT-DIR], ...)
# DX_DOXYGEN_FEATURE(ON|OFF)
# DX_DOT_FEATURE(ON|OFF)
# DX_HTML_FEATURE(ON|OFF)
# DX_CHM_FEATURE(ON|OFF)
# DX_CHI_FEATURE(ON|OFF)
# DX_MAN_FEATURE(ON|OFF)
# DX_RTF_FEATURE(ON|OFF)
# DX_XML_FEATURE(ON|OFF)
# DX_PDF_FEATURE(ON|OFF)
# DX_PS_FEATURE(ON|OFF)
#
# DESCRIPTION
#
# The DX_*_FEATURE macros control the default setting for the given
# Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for
# generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML
# help (for MS users), 'CHI' for generating a seperate .chi file by the
# .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate
# output formats. The environment variable DOXYGEN_PAPER_SIZE may be
# specified to override the default 'a4wide' paper size.
#
# By default, HTML, PDF and PS documentation is generated as this seems to
# be the most popular and portable combination. MAN pages created by
# Doxygen are usually problematic, though by picking an appropriate subset
# and doing some massaging they might be better than nothing. CHM and RTF
# are specific for MS (note that you can't generate both HTML and CHM at
# the same time). The XML is rather useless unless you apply specialized
# post-processing to it.
#
# The macros mainly control the default state of the feature. The use can
# override the default by specifying --enable or --disable. The macros
# ensure that contradictory flags are not given (e.g.,
# --enable-doxygen-html and --enable-doxygen-chm,
# --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each
# feature will be automatically disabled (with a warning) if the required
# programs are missing.
#
# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
# with the following parameters: a one-word name for the project for use
# as a filename base etc., an optional configuration file name (the
# default is '$(srcdir)/Doxyfile', the same as Doxygen's default), and an
# optional output directory name (the default is 'doxygen-doc'). To run
# doxygen multiple times for different configuration files and output
# directories provide more parameters: the second, forth, sixth, etc
# parameter are configuration file names and the third, fifth, seventh,
# etc parameter are output directories. No checking is done to catch
# duplicates.
#
# Automake Support
#
# The DX_RULES substitution can be used to add all needed rules to the
# Makefile. Note that this is a substitution without being a variable:
# only the @DX_RULES@ syntax will work.
#
# The provided targets are:
#
# doxygen-doc: Generate all doxygen documentation.
#
# doxygen-run: Run doxygen, which will generate some of the
# documentation (HTML, CHM, CHI, MAN, RTF, XML)
# but will not do the post processing required
# for the rest of it (PS, PDF).
#
# doxygen-ps: Generate doxygen PostScript documentation.
#
# doxygen-pdf: Generate doxygen PDF documentation.
#
# Note that by default these are not integrated into the automake targets.
# If doxygen is used to generate man pages, you can achieve this
# integration by setting man3_MANS to the list of man pages generated and
# then adding the dependency:
#
# $(man3_MANS): doxygen-doc
#
# This will cause make to run doxygen and generate all the documentation.
#
# The following variable is intended for use in Makefile.am:
#
# DX_CLEANFILES = everything to clean.
#
# Then add this variable to MOSTLYCLEANFILES.
#
# LICENSE
#
# Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
# Copyright (c) 2015 Olaf Mandel <olaf@mandel.name>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 20
## ----------##
## Defaults. ##
## ----------##
DX_ENV=""
AC_DEFUN([DX_FEATURE_doc], ON)
AC_DEFUN([DX_FEATURE_dot], OFF)
AC_DEFUN([DX_FEATURE_man], OFF)
AC_DEFUN([DX_FEATURE_html], ON)
AC_DEFUN([DX_FEATURE_chm], OFF)
AC_DEFUN([DX_FEATURE_chi], OFF)
AC_DEFUN([DX_FEATURE_rtf], OFF)
AC_DEFUN([DX_FEATURE_xml], OFF)
AC_DEFUN([DX_FEATURE_pdf], ON)
AC_DEFUN([DX_FEATURE_ps], ON)
## --------------- ##
## Private macros. ##
## --------------- ##
# DX_ENV_APPEND(VARIABLE, VALUE)
# ------------------------------
# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen and add it
# as a substitution (but not a Makefile variable). The substitution
# is skipped if the variable name is VERSION.
AC_DEFUN([DX_ENV_APPEND],
[AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])dnl
m4_if([$1], [VERSION], [], [AC_SUBST([$1], [$2])dnl
AM_SUBST_NOTMAKE([$1])])dnl
])
# DX_DIRNAME_EXPR
# ---------------
# Expand into a shell expression prints the directory part of a path.
AC_DEFUN([DX_DIRNAME_EXPR],
[[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
# -------------------------------------
# Expands according to the M4 (static) status of the feature.
AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
# ----------------------------------
# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
AC_DEFUN([DX_REQUIRE_PROG], [
AC_PATH_TOOL([$1], [$2])
if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
fi
])
# DX_TEST_FEATURE(FEATURE)
# ------------------------
# Expand to a shell expression testing whether the feature is active.
AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
# -------------------------------------------------
# Verify that a required features has the right state before trying to turn on
# the DX_CURRENT_FEATURE.
AC_DEFUN([DX_CHECK_DEPEND], [
test "$DX_FLAG_$1" = "$2" \
|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
requires, contradicts) doxygen-DX_CURRENT_FEATURE])
])
# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
# ----------------------------------------------------------
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
AC_DEFUN([DX_CLEAR_DEPEND], [
test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
])
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
# CHECK_DEPEND, CLEAR_DEPEND,
# REQUIRE, DO-IF-ON, DO-IF-OFF)
# --------------------------------------------
# Parse the command-line option controlling a feature. CHECK_DEPEND is called
# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
# otherwise CLEAR_DEPEND is called to turn off the default state if a required
# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
AC_DEFUN([DX_ARG_ABLE], [
AC_DEFUN([DX_CURRENT_FEATURE], [$1])
AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
AC_ARG_ENABLE(doxygen-$1,
[AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
[--enable-doxygen-$1]),
DX_IF_FEATURE([$1], [don't $2], [$2]))],
[
case "$enableval" in
#(
y|Y|yes|Yes|YES)
AC_SUBST([DX_FLAG_$1], 1)
$3
;; #(
n|N|no|No|NO)
AC_SUBST([DX_FLAG_$1], 0)
;; #(
*)
AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
;;
esac
], [
AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
$4
])
if DX_TEST_FEATURE([$1]); then
$5
:
fi
if DX_TEST_FEATURE([$1]); then
$6
:
else
$7
:
fi
])
## -------------- ##
## Public macros. ##
## -------------- ##
# DX_XXX_FEATURE(DEFAULT_STATE)
# -----------------------------
AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])])
AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR], ...)
# --------------------------------------------------------------
# PROJECT also serves as the base name for the documentation files.
# The default CONFIG-FILE is "$(srcdir)/Doxyfile" and OUTPUT-DOC-DIR is
# "doxygen-doc".
# More arguments are interpreted as interleaved CONFIG-FILE and
# OUTPUT-DOC-DIR values.
AC_DEFUN([DX_INIT_DOXYGEN], [
# Files:
AC_SUBST([DX_PROJECT], [$1])
AC_SUBST([DX_CONFIG], ['ifelse([$2], [], [$(srcdir)/Doxyfile], [$2])'])
AC_SUBST([DX_DOCDIR], ['ifelse([$3], [], [doxygen-doc], [$3])'])
m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2,
[AC_SUBST([DX_CONFIG]m4_eval(DX_i[/2]),
'm4_default_nblank_quoted(m4_argn(DX_i, $@),
[$(srcdir)/Doxyfile])')])])dnl
m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 5, m4_count($@,), 2,
[AC_SUBST([DX_DOCDIR]m4_eval([(]DX_i[-1)/2]),
'm4_default_nblank_quoted(m4_argn(DX_i, $@),
[doxygen-doc])')])])dnl
m4_define([DX_loop], m4_dquote(m4_if(m4_eval(3 < m4_count($@)), 1,
[m4_for([DX_i], 4, m4_count($@), 2, [, m4_eval(DX_i[/2])])],
[])))dnl
# Environment variables used inside doxygen.cfg:
DX_ENV_APPEND(SRCDIR, $srcdir)
DX_ENV_APPEND(PROJECT, $DX_PROJECT)
DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
# Doxygen itself:
DX_ARG_ABLE(doc, [generate any doxygen documentation],
[],
[],
[DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
DX_REQUIRE_PROG([DX_PERL], perl)],
[DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
# Dot for graphics:
DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_DOT], dot)],
[DX_ENV_APPEND(HAVE_DOT, YES)
DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
[DX_ENV_APPEND(HAVE_DOT, NO)])
# Man pages generation:
DX_ARG_ABLE(man, [generate doxygen manual pages],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_MAN, YES)],
[DX_ENV_APPEND(GENERATE_MAN, NO)])
# RTF file generation:
DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_RTF, YES)],
[DX_ENV_APPEND(GENERATE_RTF, NO)])
# XML file generation:
DX_ARG_ABLE(xml, [generate doxygen XML documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_XML, YES)],
[DX_ENV_APPEND(GENERATE_XML, NO)])
# (Compressed) HTML help generation:
DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_HHC], hhc)],
[DX_ENV_APPEND(HHC_PATH, $DX_HHC)
DX_ENV_APPEND(GENERATE_HTML, YES)
DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
[DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
# Seperate CHI file generation.
DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
[DX_CHECK_DEPEND(chm, 1)],
[DX_CLEAR_DEPEND(chm, 1)],
[],
[DX_ENV_APPEND(GENERATE_CHI, YES)],
[DX_ENV_APPEND(GENERATE_CHI, NO)])
# Plain HTML pages generation:
DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
[DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
[DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
[],
[DX_ENV_APPEND(GENERATE_HTML, YES)],
[DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
# PostScript file generation:
DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_LATEX], latex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_DVIPS], dvips)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# PDF file generation:
DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# LaTeX generation for PS and/or PDF:
if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
DX_ENV_APPEND(GENERATE_LATEX, YES)
else
DX_ENV_APPEND(GENERATE_LATEX, NO)
fi
# Paper size for PS and/or PDF:
AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
[a4wide (default), a4, letter, legal or executive])
case "$DOXYGEN_PAPER_SIZE" in
#(
"")
AC_SUBST(DOXYGEN_PAPER_SIZE, "")
;; #(
a4wide|a4|letter|legal|executive)
DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
;; #(
*)
AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
;;
esac
# Rules:
AS_IF([[test $DX_FLAG_html -eq 1]],
[[DX_SNIPPET_html="## ------------------------------- ##
## Rules specific for HTML output. ##
## ------------------------------- ##
DX_CLEAN_HTML = \$(DX_DOCDIR)/html]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/html]])[
"]],
[[DX_SNIPPET_html=""]])
AS_IF([[test $DX_FLAG_chi -eq 1]],
[[DX_SNIPPET_chi="
DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).chi]])["]],
[[DX_SNIPPET_chi=""]])
AS_IF([[test $DX_FLAG_chm -eq 1]],
[[DX_SNIPPET_chm="## ------------------------------ ##
## Rules specific for CHM output. ##
## ------------------------------ ##
DX_CLEAN_CHM = \$(DX_DOCDIR)/chm]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/chm]])[\
${DX_SNIPPET_chi}
"]],
[[DX_SNIPPET_chm=""]])
AS_IF([[test $DX_FLAG_man -eq 1]],
[[DX_SNIPPET_man="## ------------------------------ ##
## Rules specific for MAN output. ##
## ------------------------------ ##
DX_CLEAN_MAN = \$(DX_DOCDIR)/man]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/man]])[
"]],
[[DX_SNIPPET_man=""]])
AS_IF([[test $DX_FLAG_rtf -eq 1]],
[[DX_SNIPPET_rtf="## ------------------------------ ##
## Rules specific for RTF output. ##
## ------------------------------ ##
DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/rtf]])[
"]],
[[DX_SNIPPET_rtf=""]])
AS_IF([[test $DX_FLAG_xml -eq 1]],
[[DX_SNIPPET_xml="## ------------------------------ ##
## Rules specific for XML output. ##
## ------------------------------ ##
DX_CLEAN_XML = \$(DX_DOCDIR)/xml]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/xml]])[
"]],
[[DX_SNIPPET_xml=""]])
AS_IF([[test $DX_FLAG_ps -eq 1]],
[[DX_SNIPPET_ps="## ----------------------------- ##
## Rules specific for PS output. ##
## ----------------------------- ##
DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps]])[
DX_PS_GOAL = doxygen-ps
doxygen-ps: \$(DX_CLEAN_PS)
]m4_foreach([DX_i], [DX_loop],
[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
\$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
\$(DX_LATEX) refman.tex; \\
\$(DX_MAKEINDEX) refman.idx; \\
\$(DX_LATEX) refman.tex; \\
countdown=5; \\
while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
refman.log > /dev/null 2>&1 \\
&& test \$\$countdown -gt 0; do \\
\$(DX_LATEX) refman.tex; \\
countdown=\`expr \$\$countdown - 1\`; \\
done; \\
\$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi
]])["]],
[[DX_SNIPPET_ps=""]])
AS_IF([[test $DX_FLAG_pdf -eq 1]],
[[DX_SNIPPET_pdf="## ------------------------------ ##
## Rules specific for PDF output. ##
## ------------------------------ ##
DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf]])[
DX_PDF_GOAL = doxygen-pdf
doxygen-pdf: \$(DX_CLEAN_PDF)
]m4_foreach([DX_i], [DX_loop],
[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
\$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
\$(DX_PDFLATEX) refman.tex; \\
\$(DX_MAKEINDEX) refman.idx; \\
\$(DX_PDFLATEX) refman.tex; \\
countdown=5; \\
while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
refman.log > /dev/null 2>&1 \\
&& test \$\$countdown -gt 0; do \\
\$(DX_PDFLATEX) refman.tex; \\
countdown=\`expr \$\$countdown - 1\`; \\
done; \\
mv refman.pdf ../\$(PACKAGE).pdf
]])["]],
[[DX_SNIPPET_pdf=""]])
AS_IF([[test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1]],
[[DX_SNIPPET_latex="## ------------------------------------------------- ##
## Rules specific for LaTeX (shared for PS and PDF). ##
## ------------------------------------------------- ##
DX_V_LATEX = \$(_DX_v_LATEX_\$(V))
_DX_v_LATEX_ = \$(_DX_v_LATEX_\$(AM_DEFAULT_VERBOSITY))
_DX_v_LATEX_0 = @echo \" LATEX \" \$][@;
DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/latex]])[
"]],
[[DX_SNIPPET_latex=""]])
AS_IF([[test $DX_FLAG_doc -eq 1]],
[[DX_SNIPPET_doc="## --------------------------------- ##
## Format-independent Doxygen rules. ##
## --------------------------------- ##
${DX_SNIPPET_html}\
${DX_SNIPPET_chm}\
${DX_SNIPPET_man}\
${DX_SNIPPET_rtf}\
${DX_SNIPPET_xml}\
${DX_SNIPPET_ps}\
${DX_SNIPPET_pdf}\
${DX_SNIPPET_latex}\
DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V))
_DX_v_DXGEN_ = \$(_DX_v_DXGEN_\$(AM_DEFAULT_VERBOSITY))
_DX_v_DXGEN_0 = @echo \" DXGEN \" \$<;
.PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
.INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
doxygen-run:]m4_foreach([DX_i], [DX_loop],
[[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag]])[
doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
]m4_foreach([DX_i], [DX_loop],
[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag: \$(DX_CONFIG]DX_i[) \$(pkginclude_HEADERS)
\$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR]DX_i[) \$(DX_DOXYGEN) \$(DX_CONFIG]DX_i[)
\$(A""M_V_at)echo Timestamp >\$][@
]])dnl
[DX_CLEANFILES = \\]
m4_foreach([DX_i], [DX_loop],
[[ \$(DX_DOCDIR]DX_i[)/doxygen_sqlite3.db \\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \\
]])dnl
[ -r \\
\$(DX_CLEAN_HTML) \\
\$(DX_CLEAN_CHM) \\
\$(DX_CLEAN_CHI) \\
\$(DX_CLEAN_MAN) \\
\$(DX_CLEAN_RTF) \\
\$(DX_CLEAN_XML) \\
\$(DX_CLEAN_PS) \\
\$(DX_CLEAN_PDF) \\
\$(DX_CLEAN_LATEX)"]],
[[DX_SNIPPET_doc=""]])
AC_SUBST([DX_RULES],
["${DX_SNIPPET_doc}"])dnl
AM_SUBST_NOTMAKE([DX_RULES])
#For debugging:
#echo DX_FLAG_doc=$DX_FLAG_doc
#echo DX_FLAG_dot=$DX_FLAG_dot
#echo DX_FLAG_man=$DX_FLAG_man
#echo DX_FLAG_html=$DX_FLAG_html
#echo DX_FLAG_chm=$DX_FLAG_chm
#echo DX_FLAG_chi=$DX_FLAG_chi
#echo DX_FLAG_rtf=$DX_FLAG_rtf
#echo DX_FLAG_xml=$DX_FLAG_xml
#echo DX_FLAG_pdf=$DX_FLAG_pdf
#echo DX_FLAG_ps=$DX_FLAG_ps
#echo DX_ENV=$DX_ENV
])
+21 -3
View File
@@ -2,7 +2,7 @@ lib_LTLIBRARIES = libite.la
libite_la_CPPFLAGS = -D_GNU_SOURCE
libite_la_CFLAGS = -W -Wall -Wextra
libite_la_LDFLAGS = $(AM_LDFLAGS) -version-info 8:0:3
libite_la_LDFLAGS = $(AM_LDFLAGS) -version-info 8:1:3
libite_la_SOURCES = chomp.c copyfile.c \
conio.c conio.h dir.c \
erasef.c fopenf.c fremove.c \
@@ -21,7 +21,25 @@ libite_la_SOURCES = chomp.c copyfile.c \
queue.h tree.h
## Distribute these header files in the <lite/...> name space
pkgincludedir = $(includedir)/lite
## Distribute these header files in the <libite/...> namespace
pkgincludedir = $(includedir)/libite
pkginclude_HEADERS = lite.h queue.h conio.h tree.h strlite.h strdupa.h \
strndupa.h strnlen.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libite.pc
## For compatibility with previous <lite/...> namespace
if COMPAT_SYMLINK
install-data-hook:
link=$(DESTDIR)$(includedir)/lite; \
if [ ! -f $$link ]; then \
$(LN_S) libite $$link; \
fi
uninstall-hook:
link=$(shell readlink $(DESTDIR)$(includedir)/lite); \
if [ "$$link" = "libite" ]; then \
$(RM) $(DESTDIR)$(includedir)/lite; \
fi
endif
+11 -5
View File
@@ -15,19 +15,25 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file chomp.c
* @author Joachim Wiberg
* @date 2014-2021
* @copyright ISC License
*/
#include <errno.h>
#include <string.h>
/**
* chomp - Perl like chomp function, chop off last char(s) if newline.
* @str: String to chomp
* Perl like chomp function, chop off last char(s) if newline.
* @param str String to chomp
*
* This function is like Perl chomp, but it's set to chop of all
* trailing newlines. Useful in combination with fgets().
*
* Returns:
* If @str is a valid pointer this function returns @str, otherwise
* @errno is set to %EINVAL and this function returns %NULL.
* @returns @a str, or @c NULL with @a errno set, if @a str is not a valid pointer.
* @exception EINVAL if the input argument is not a valid pointer.
*/
char *chomp(char *str)
{
+21
View File
@@ -15,11 +15,32 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file conio.c
* @author Joachim Wiberg
* @date 2009-2021
* @copyright ISC License
*/
#include <poll.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
/**
* Probe terminal size
* @param row pointer to integer to store number of rows
* @param col pointer to integer to store number of columns
*
* This function checks if stdin and stdout isatty() and then sets the
* TTY in raw mode to silently ask the size using ANSI escape sequences.
* This is achieved by trying to go to corner 999,999 followed by
* querying the cursor position. Afterwards the TTY is returned to the
* state if was before, e.g. cooked. The number of rows and columns is
* returned in the input arguments to this function.
*
* If stdio is @a not a TTY, then a default 24x80 is returned.
*/
void initscr(int *row, int *col)
{
if (!row || !col)
+41 -15
View File
@@ -15,17 +15,26 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file conio.h
* @author Joachim Wiberg
* @date 2009-2021
* @copyright ISC License
*
* Helper macros and functions for interacting with TTY terminals.
*/
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef CONIO_H_
#define CONIO_H_
#ifndef LIBITE_CONIO_H_
#define LIBITE_CONIO_H_
#include <stdio.h>
/* Attributes */
/** Attributes */
#define RESETATTR 0
#define BRIGHT 1
#define DIM 2
@@ -34,7 +43,7 @@ extern "C"
#define REVERSE 7
#define HIDDEN 8
/* Colors for text and background */
/** Colors for text and background */
#define BLACK 0x0
#define RED 0x1
#define GREEN 0x2
@@ -54,39 +63,50 @@ extern "C"
#define WHITE 0x17
#ifndef SCREEN_WIDTH
#define SCREEN_WIDTH 80 /* Override using, e.g. #define SCREEN_WIDTH tty_width() */
#define SCREEN_WIDTH 80 /**< Fallback screen width, possible to override. */
#endif
/* Esc[2JEsc[1;1H - Clear screen and move cursor to 1,1 (upper left) pos. */
/** Clear screen and move cursor to 1,1 (upper left) pos. */
#define clrscr() fputs("\033[2J\033[1;1H", stdout)
/* Esc[K - Erases from the current cursor position to the end of the current line. */
/** Erases from the current cursor position to the end of the current line. */
#define clreol() fputs("\033[K", stdout)
/* Esc[2K - Erases the entire current line. */
/** Erases the entire current line. */
#define delline() fputs("\033[2K", stdout)
/* Esc[Line;ColumnH - Moves the cursor to the specified position (coordinates) */
/** Moves the cursor to the specified position (coordinates) */
#define gotoxy(x,y) fprintf(stdout, "\033[%d;%dH", y, x)
/* Esc[?25l (lower case L) - Hide Cursor */
/** Hide Cursor */
#define hidecursor() fputs("\033[?25l", stdout)
/* Esc[?25h (lower case H) - Show Cursor */
/** Show Cursor */
#define showcursor() fputs("\033[?25h", stdout)
/* Esc[Value;...;Valuem - Set Graphics Mode (attr, color, val) */
/** Set Graphics Mode (attr, color, val) */
#define __set_gm(a,c,v) \
if (!c) \
fprintf(stdout, "\033[%dm", a); \
else \
fprintf(stdout, "\033[%d;%dm", c & 0x10 ? 1 : 0, (c & 0xF) + v)
/** Set text attribute */
#define textattr(attr) __set_gm(attr, 0, 0)
/** Set text color */
#define textcolor(color) __set_gm(RESETATTR, color, 30)
/** Set text background */
#define textbackground(color) __set_gm(RESETATTR, color, 40)
void initscr(int *row, int *col);
/* Print table heading @line to @fp, with optional leading newline
* Example:
/**
* Print table heading, with optional leading newline.
* @param fp output stream
* @param line string to print
* @param nl leading newline or not
* @param attr attribute
*
* @verbatim
* _________________ <-- Empty line with UNDERSCORE to frame first heading
* First heading <-- In normal/RESETATTR
* SUBHEADING <-- In REVERSE and with capital letters like 'top'
* @endverbatim
*/
static inline void printhdr(FILE *fp, const char *line, int nl, int attr)
{
@@ -99,12 +119,18 @@ static inline void printhdr(FILE *fp, const char *line, int nl, int attr)
SCREEN_WIDTH - (int)strlen(line), "");
}
/**
* Print reverse mode table heading, e.g. black text on white background.
* @param fp output stream
* @param line string to print
* @param nl leading newline or not
*/
static inline void printheader(FILE *fp, const char *line, int nl)
{
printhdr(fp, line, nl, REVERSE);
}
#endif /* CONIO_H_ */
#endif /* LIBITE_CONIO_H_ */
#ifdef __cplusplus
}
+34 -30
View File
@@ -21,6 +21,13 @@
* THE SOFTWARE.
*/
/**
* @file copyfile.c
* @author Claudio Matsuoka
* @date 2008
* @copyright MIT License
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -94,28 +101,30 @@ static void set_mtime(int in, int out)
}
/**
* copyfile - Copy a file to another.
* @src: Full path name to source file.
* @dst: Full path name to target file.
* @len: Number of bytes to copy, zero (0) for entire file.
* @opt: An option mask of %LITE_FOPT_COPYFILE_SYM, %LITE_FOPT_KEEP_MTIME
* Copy a file to another.
* @param src Full path name to source file.
* @param dst Full path name to target file.
* @param len Number of bytes to copy, zero (0) for entire file.
* @param opt An option mask of ::LITE_FOPT_COPYFILE_SYM, ::LITE_FOPT_KEEP_MTIME
*
* This is a C implementation of the command line cp(1) utility. It is one
* of the classic missing links in the UNIX C library. This version is from
* the finit project, http://helllabs.org/finit/, which is a reimplementation
* of fastinit for the Asus EeePC.
*
* The @opt field replaces the @sym argument in previous releases and
* works as follows. To maintain backwards compatibility with @sym
* the %LITE_FOPT_COPYFILE_SYM maintains a value of 1:
* The @a opt field replaces the @a sym argument in previous releases
* and works as follows. To maintain backwards compatibility with @a
* sym the ::LITE_FOPT_COPYFILE_SYM has a value of @c 1. Supported
* option flags are:
*
* %LITE_FOPT_COPYFILE_SYM: Recreate symlink or follow to copy target
* %LITE_FOPT_KEEP_MTIME: Preserve modification time
* - ::LITE_FOPT_COPYFILE_SYM Recreate symlink or follow to copy target
* - ::LITE_FOPT_KEEP_MTIME Preserve modification time
*
* Returns:
* The number of bytes copied, zero may be error (check errno!), but it
* may also indicate that @src was empty. If @src is a directory @errno
* will be set to %EISDIR since copyfile() is not recursive.
* @returns The number of bytes copied, or zero, which may be an error
* (check @a errno, see Exceptions below), but it may also indicate that
* @a src was empty. See exceptions, below.
*
* @exception EISDIR if @a src is a directory, since copyfile() is not recursive.
*/
ssize_t copyfile(const char *src, const char *dst, int len, int opt)
{
@@ -203,20 +212,19 @@ exit:
}
/**
* movefile - Move a file to another location
* @src: Source file.
* @dst: Target file, or location.
* Move a file to another location
* @param src Source file.
* @param dst Target file, or location.
*
* This is a C implementation of the command line mv(1) utility.
* Usually the rename() API is sufficient, but not when moving across
* file system boundaries.
*
* The @src argument must include the full path to the source file,
* whereas the @dst argument may only be a directory, in which case the
* same file name from @src is used.
* The @p src argument must include the full path to the source file,
* whereas the @p dst argument may only be a directory, in which case
* the same file name from @p src is used.
*
* Returns:
* POSIX OK(0), or non-zero with errno set.
* @returns POSIX OK(0), or non-zero with @a errno set.
*/
int movefile(const char *src, const char *dst)
{
@@ -246,15 +254,11 @@ int movefile(const char *src, const char *dst)
}
/**
* fcopyfile - Copy between FILE *fp.
* @src: Source FILE.
* @dst: Destination FILE.
* Copy between FILE *fp.
* @param src Source FILE.
* @param dst Destination FILE.
*
* Function takes signals into account and will restart the syscalls as
* long as error is %EINTR.
*
* Returns:
* POSIX OK(0), or non-zero with errno set on error.
* @returns POSIX OK(0), or non-zero with @a errno set on error.
*/
int fcopyfile(FILE *src, FILE *dst)
{
+24 -20
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file dir.c
* @author Joachim Wiberg
* @date 2008-2021
* @copyright ISC License
*/
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
@@ -48,32 +55,29 @@ static int matcher(const struct dirent *entry)
}
/**
* dir - List all files of a certain type in the given directory.
* @dir: Base directory for dir operation.
* @type: File type suffix, e.g. ".cfg".
* @filter: Optional file name filter.
* @list: Pointer to an array of file names.
* @strip: Flag, if set dir() strips the file type.
* List all files of a certain type in the given directory.
* @param dir Base directory for dir operation.
* @param type File type suffix, e.g. ".cfg".
* @param filter Optional file name filter.
* @param list Pointer to an array of file names.
* @param strip Flag, if set dir() strips the file type.
*
* This function returns a @list of files, matching the @type suffix,
* in the given directory @dir.
* This function returns a @a list of files, matching the @a type
* suffix, in the given directory @a dir.
*
* The @list argument is a pointer to where to store the dynamically
* The @a list argument is a pointer to where to store the dynamically
* allocated list of file names. This list should be free'd by first
* calling free() on each file name and then on the list itself.
*
* If @filter is not %NULL it will be called for each file found. If
* @filter returns non-zero the @file argument will be included in the
* resulting @list. If @filter returns zero for given @file it will
* be discarded.
* If @a filter is not @c NULL it will be called for each file found.
* If @a filter returns non-zero the @a file argument is included in the
* resulting @a list. If @a filter returns zero for given @a file it is
* discarded. If the @a strip flag is set the resulting @a list of
* files has their file type stripped, including the dot. So a match
* "config0.cfg" would be returned as "config0".
*
* If the @strip flag is set the resulting @list of files has their
* file type stripped, including the dot. So a match "config0.cfg"
* would be returned as "config0".
*
* Returns:
* Number of files in @list, zero if no matching files of @type, or
* non-zero on error with @errno set.
* @returns The number of files in @a list, zero if no matching files of
* @a type, or non-zero on error with @a errno set.
*/
int dir(const char *dir, const char *type, int (*filter) (const char *file), char ***list, int strip)
{
+11 -5
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file erasef.c
* @author Joachim Wiberg
* @date 2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
@@ -24,16 +31,15 @@
#include "lite.h"
/**
* erasef - Like erase() but with formatted string support
* @fmt: Formatted string to be composed into a pathname
* Like erase() but with formatted string support.
* @param fmt Formatted string to be composed into a pathname
*
* This is a wrapper for the erase() function in lite.h, lessening the
* burden of having to compose the filename from parts in a seprate
* buffer.
*
* Returns:
* Upon successful completion erasef() returns POSIX OK(0), otherwise,
* -1 is returned and errno is set to indicate the error.
* @returns Upon successful completion erasef() returns POSIX OK(0),
* otherwise, -1 is returned and @a errno is set to indicate the error.
*/
int erasef(const char *fmt, ...)
{
+10 -4
View File
@@ -21,15 +21,21 @@
* THE SOFTWARE.
*/
/**
* @file fexist.c
* @author Claudio Matsuoka
* @date 2008
* @copyright MIT License
*/
#include <errno.h>
#include <unistd.h>
/**
* fexist - Check if a file exists in the file system.
* @file: File to look for, with full path.
* Check if a file exists in the file system.
* @param file File to look for, with full path.
*
* Returns:
* %TRUE(1) if the file exists, otherwise %FALSE(0).
* @returns @c TRUE(1) if the @a file exists, otherwise @c FALSE(0).
*/
int fexist(const char *file)
{
+10 -4
View File
@@ -21,15 +21,21 @@
* THE SOFTWARE.
*/
/**
* @file fisdir.c
* @author Claudio Matsuoka
* @date 2008
* @copyright MIT License
*/
#include <sys/stat.h>
#include <unistd.h>
/**
* fisdir - Check if a path exists and is a directory.
* @path: Path to file or directory
* Check if a path exists and is a directory.
* @param path Path to file or directory
*
* Returns:
* %TRUE(1) if @path exists and is a directory, otherwise %FALSE(0).
* @returns @c TRUE(1) if @p path exists and is a directory, otherwise @c FALSE(0).
*/
int fisdir(const char *path)
{
+13 -6
View File
@@ -15,22 +15,29 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file fopenf.c
* @author Joachim Wiberg
* @date 2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
/**
* fopenf - Open a file based on the formatted string and optional arguments
* @mode: Last argument in optional list, if omitted EINVAL
* @fmt: Formatted string to be composed into a pathname
* Open a file based on the formatted string and optional arguments
* @param mode An fopen() mode string, e.g. "w+"
* @param fmt Formatted string to be composed into a pathname
*
* This function is an extension to the fopen() family, lessening the burden
* of first having to compose the filename from parts in a seprate buffer.
*
* Returns:
* Upon successful completion fopenf() a FILE pointer. Otherwise, NULL
* is returned and errno is set to indicate the error.
* @returns Upon successful completion, fopenf() returns a FILE pointer.
* Otherwise, @c NULL is returned and @a errno is set to indicate the
* error.
*/
FILE *fopenf(const char *mode, const char *fmt, ...)
{
+26 -4
View File
@@ -24,6 +24,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file fparseln.c
* @author Christos Zoulas
* @date 1997
* @copyright 2-clause BSD License
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
@@ -63,10 +70,25 @@ isescaped(const char *sp, const char *p, int esc)
}
/* fparseln():
* Read a line from a file parsing continuations ending in \
* and eliminating trailing newlines, or comments starting with
* the comment char.
/**
* Read a line from a file parsing continuations and trailing newlines
* @param fp FILE pointer to read from
* @param size The resulting length of the string, unused if @c NULL
* @param lineno Incremented with number of lines read, unused if @c NULL
* @param str Characters to look for, escape character, continuation, and comment
* @param flags ::FPARSELN_UNESCCOMM, ::FPARSELN_UNESCCONT, ::FPARSELN_UNESCESC, ::FPARSELN_UNESCREST, ::FPARSELN_UNESCALL
*
* This function reads a line from a file, parsing continuations ending
* in '\' and eliminating trailing newlines, or comments starting with
* the comment char '#'.
*
* If @a size is not @c NULL, the resulting length of the returned string
* is stored in @a size.
*
* If @a lineno is not @c NULL, it is incremented for each actual line
* read from @a fp.
*
* @returns the line read from @a fp, or @c NULL on EOF or error.
*/
char *
fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
+11 -4
View File
@@ -15,20 +15,27 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file fremove.c
* @author Joachim Wiberg
* @date 2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
/**
* fremove - Remove a file based on the formatted string and optional arguments
* @fmt: Formatted string to be composed into a pathname
* Remove a file based on the formatted string and optional arguments
* @param fmt Formatted string to be composed into a pathname
*
* This function is an extension to remove(), lessening the burden of
* first having to compose the filename from parts in a seprate buffer.
*
* Returns:
* Return value for remove(3).
* @returns same as remove(3), with an extra @a errno, @c ENOBUFS if
* alloca() fails to get a temporary buffer for composing the file name.
*/
int fremove(const char *fmt, ...)
{
+18 -11
View File
@@ -21,25 +21,32 @@
* THE SOFTWARE.
*/
/**
* @file fsendfile.c
* @author Tobias Waldekranz
* @date 2013
* @copyright MIT License
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
/**
* fsendfile - copy data between file streams
* @src: Source stream
* @dst: Destination stream
* @len: Number of bytes to copy
* Copy data between file streams.
* @param src Source stream
* @param dst Destination stream
* @param len Number of bytes to copy
*
* @dst may be %NULL, in which case @len bytes are read and discarded
* from @src. This can be useful for streams where seeking is not
* permitted. Additionally, @len may be the special value zero (0), in
* which case fsendfile() will copy until %EOF is seen on @src.
* The @p dst argument may be @c NULL, in which case @a len bytes are
* read and discarded from @a src. This can be useful for streams where
* seeking is not permitted. Additionally, @a len may be the special
* value zero (0), in which case fsendfile() copies until @c EOF is seen
* on @a src.
*
* Returns:
* The number of bytes copied. If an error is detected -1 is returned
* and @errno will be set accordingly.
* @returns The number of bytes copied. If an error is detected -1 is
* returned and @a errno will be set accordingly.
*/
ssize_t fsendfile(FILE *src, FILE *dst, size_t len)
{
+14 -7
View File
@@ -22,6 +22,14 @@
* THE SOFTWARE.
*/
/**
* @file ifconfig.c
* @author Claudio Matsuoka
* @author Joachim Wiberg
* @date 2008-2021
* @copyright MIT License
*/
#include <arpa/inet.h>
#include <errno.h>
#include <net/if.h>
@@ -34,14 +42,13 @@
extern size_t strlcpy(char *dst, const char *src, size_t siz);
/**
* ifconfig - Basic ifconfig like operations on an interface
* @ifname: Name of interface to operate on
* @addr: If @up then set this optional IPv4 address
* @mask: If @up and @addr, and @addr is not INADDR_ANY, then set netmask
* @up: Control %IFF_UP flag on interface
* Basic ifconfig like operations on an interface
* @param ifname Name of interface to operate on
* @param addr If @p up then set this optional IPv4 address
* @param mask If @p up and @p addr, and @p addr is not @c INADDR_ANY, then set netmask
* @param up Control @c IFF_UP flag on interface
*
* Returns:
* POSIX OK(0) on success, or non-zero on error.
* @returns POSIX OK(0) on success, or non-zero on error.
*/
int ifconfig(const char *ifname, const char *addr, const char *mask, int up)
{
+38 -35
View File
@@ -15,26 +15,33 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file lfile.c
* @author Joachim Wiberg
* @date 2015-2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h> /* FILE */
#include <stdlib.h> /* atoi() */
#include <string.h> /* strlen(), strncmp(), strtok_r() */
#include <sys/param.h> /* MAX() */
/** @private for internal use only */
typedef struct lfile {
FILE *fp;
char buf[256];
char *save;
const char *sep;
FILE *fp; /**< FILE pointer to current stream */
char buf[256]; /**< Internal buffer, limted to 256 bytes per line */
char *save; /**< Internal save pointer */
const char *sep; /**< Record separator, from lfopen() */
} lfile_t;
/**
* lfopen - Open file and return parsing context
* @file: File to parse
* @sep: Separator(s) to use in lftok()
* Open file and return parsing context.
* @param file File to parse
* @param sep Separator(s) to use in lftok()
*
* Returns:
* Pointer to a &lftile_t parser context, or %NULL on error.
* @returns Pointer to an @a lfile_t parser context, or @c NULL on error.
*/
lfile_t *lfopen(const char *file, const char *sep)
{
@@ -62,8 +69,8 @@ lfile_t *lfopen(const char *file, const char *sep)
}
/**
* lfclose - Close a parser context
* @lf: Pointer to &lfile_t context from lfopen()
* Close a parser context.
* @param lf: Pointer to @a lfile_t parser context from lfopen()
*/
void lfclose(lfile_t *lf)
{
@@ -76,12 +83,11 @@ void lfclose(lfile_t *lf)
}
/**
* lftok - Get next token in file
* @lf: Pointer to &lfile_t context from lfopen()
* Get next token in file
* @param lf: Pointer to @a lfile_t parser context from lfopen()
*
* Returns:
* Next token, read from file previously opened with lfopen(),
* or %NULL if EOF.
* @returns Next token, read from file previously opened with lfopen(),
* or @c NULL if EOF.
*/
char *lftok(lfile_t *lf)
{
@@ -110,18 +116,17 @@ char *lftok(lfile_t *lf)
}
/**
* lfgetkey - Find key in file
* @lf: Pointer to &lfile_t context from lfopen()
* @key: Key to look for
* Find key in file
* @param lf Pointer to @a lfile_t parser context from lfopen()
* @param key Key to look for
*
* Locate @key from the current position in the file parser context
* returned from lfopen(). Please note, the search for @key does not
* Locate @a key from the current position in the file parser context
* returned from lfopen(). Please note, the search for @a key does not
* start from the beginning of the file, it searches from the current
* position. To restart search from the beginning use rewind() on the
* lf->fp.
*
* Returns:
* The value to @key, or %NULL if not found.
* @returns The value to @a key, or @c NULL if not found.
*/
char *lfgetkey(lfile_t *lf, const char *key)
{
@@ -139,15 +144,14 @@ char *lfgetkey(lfile_t *lf, const char *key)
}
/**
* lfgetint - Same as lfgetkey() but returns an integer
* @lf: Pointer to &lfile_t context from lfopen()
* @key: Key to look for
* Same as lfgetkey() but returns an integer.
* @param lf Pointer to @a lfile_t parser context from lfopen()
* @param key Key to look for
*
* This function is the same as lfgetkey() but returns the positive
* integer value for the matching @key, if found.
* integer value for the matching @a key, if found.
*
* Returns:
* The positive integer value for @key, or -1 if not found.
* @returns The positive integer value for @a key, or -1 if not found.
*/
int lfgetint(lfile_t *lf, const char *key)
{
@@ -160,16 +164,15 @@ int lfgetint(lfile_t *lf, const char *key)
}
/**
* fgetint - Find the integer value for key in a file
* @file: File to search for @key
* @sep: Separator for tokens in @file
* @key: Key to look for in @file
* Find the integer value for key in a file.
* @param file File to search for @a key
* @param sep Separator for tokens in @a file
* @param key Key to look for in @a file
*
* This is a convenience wrapper for lfopen(), lfgetint(), and
* lfclose().
*
* Returns:
* The positive integer value for @key, or -1 if not found.
* @returns The positive integer value for @a key, or -1 if not found.
*/
int fgetint(const char *file, const char *sep, const char *key)
{
+1 -2
View File
@@ -8,5 +8,4 @@ Description: Frog DNA, basically
Version: @VERSION@
Requires:
Libs: -L${libdir} -lite
Cflags: -I${includedir}
Cflags: -I${includedir} -D_LIBITE_LITE
+61 -21
View File
@@ -22,13 +22,24 @@
* THE SOFTWARE.
*/
/**
* Collection of frog DNA
* @file lite.h
* @author Claudio Matsuoka (2008-2010)
* @author Joachim Wiberg (2008-2021)
* @copyright MIT License
*
* The latest version of this manual and the libite (-lite) software
* library are available at https://github.com/troglobit/libite/
*/
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef LITE_H_
#define LITE_H_
#ifndef LIBITE_LITE_H_
#define LIBITE_LITE_H_
#include <errno.h>
#include <fcntl.h> /* Definition of AT_* constants for utimensat() */
@@ -43,21 +54,21 @@ extern "C"
/*
* fparseln() specific operation flags.
*/
#define FPARSELN_UNESCESC 0x01
#define FPARSELN_UNESCCONT 0x02
#define FPARSELN_UNESCCOMM 0x04
#define FPARSELN_UNESCREST 0x08
#define FPARSELN_UNESCALL 0x0f
#define FPARSELN_UNESCESC 0x01 /**< Remove escape preceding an escaped comment. */
#define FPARSELN_UNESCCONT 0x02 /**< Remove escape preceding an escaped continuation. */
#define FPARSELN_UNESCCOMM 0x04 /**< Remove escape preceding an escaped escape. */
#define FPARSELN_UNESCREST 0x08 /**< Remove escape preceding any other character. */
#define FPARSELN_UNESCALL 0x0f /**< All of the above. */
/*
* copyfile() and rsync() option flags
*/
#define LITE_FOPT_RSYNC_DELETE 0x01
#define LITE_FOPT_COPYFILE_SYM 0x01
#define LITE_FOPT_KEEP_MTIME 0x02
#define LITE_FOPT_RSYNC_DELETE 0x01 /**< Prune files from destination that are not in source */
#define LITE_FOPT_COPYFILE_SYM 0x01 /**< Recreate symlink or follow to copy target */
#define LITE_FOPT_KEEP_MTIME 0x02 /**< Preserve modification time */
typedef struct lfile lfile_t;
typedef struct sdbuf sdbuf_t;
typedef struct lfile lfile_t; /**< Opqaue context struct for lfile APIs */
typedef struct sdbuf sdbuf_t; /**< Opqaue context struct for telnet APIs */
char *chomp (char *str);
@@ -120,6 +131,12 @@ int whichp (const char *cmd);
#ifndef touch
#include <sys/stat.h> /* utimensat() */
#include <sys/time.h> /* utimensat() on *BSD */
/**
* Create a file, ignoring errors for already existing files
* @param path Path to file to create.
*
* @returns POSIX OK(0), or non-zero on error.
*/
static inline int touch(const char *path)
{
if (utimensat(AT_FDCWD, path, NULL, 0)) {
@@ -131,6 +148,12 @@ static inline int touch(const char *path)
}
#endif
#ifndef makedir
/**
* Create a directory, ignoring errors for already existing files
* @param path Path to directory to create.
*
* @returns POSIX OK(0), or non-zero on error.
*/
static inline int makedir(const char *path, mode_t mode)
{
if (mkdir(path, mode) && errno != EEXIST)
@@ -139,6 +162,12 @@ static inline int makedir(const char *path, mode_t mode)
}
#endif
#ifndef makefifo
/**
* Create a FIFO, ignoring errors for already existing files
* @param path Path to FIFO to create.
*
* @returns POSIX OK(0), or non-zero on error.
*/
static inline int makefifo(const char *path, mode_t mode)
{
if (mkfifo(path, mode) && errno != EEXIST)
@@ -147,6 +176,12 @@ static inline int makefifo(const char *path, mode_t mode)
}
#endif
#ifndef erase
/**
* Remove a file, ignoring errors for missing files
* @param path Path to file to remove.
*
* @returns POSIX OK(0), or non-zero on error.
*/
static inline int erase(const char *path)
{
if (remove(path) && errno != ENOENT)
@@ -168,27 +203,32 @@ static inline int erase(const char *path)
/* Unline isset(), setbit() et al, these work with integers/shorts/longwords/etc. */
#ifndef ISCLR
#define ISCLR(word,bit) ((word & (1 << (bit)) ? 0 : 1))
#define ISCLR(word,bit) ((word & (1 << (bit)) ? 0 : 1)) /**< Is bit cleared in word? */
#endif
#ifndef ISSET
#define ISSET(word,bit) ((word & (1 << (bit)) ? 1 : 0))
#define ISSET(word,bit) ((word & (1 << (bit)) ? 1 : 0)) /**< Is bit set in word? */
#endif
#ifndef ISOTHER
#define ISOTHER(word,bit) ((word & ~(1 << (bit)) ? 1 : 0)) /* Is any other bit set? */
#define ISOTHER(word,bit) ((word & ~(1 << (bit)) ? 1 : 0)) /**< Is any other bit set? */
#endif
#ifndef SETBIT
#define SETBIT(word,bit) (word |= (1 << (bit)))
#define SETBIT(word,bit) (word |= (1 << (bit))) /**< Set bit in word. */
#endif
#ifndef CLRBIT
#define CLRBIT(word,bit) (word &= ~(1 << (bit)))
#define CLRBIT(word,bit) (word &= ~(1 << (bit))) /**< Clear bit in word. */
#endif
/* From The Practice of Programming, by Kernighan and Pike */
#ifndef NELEMS
#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
#define NELEMS(array) (sizeof(array) / sizeof(array[0])) /**< Number of elements in array. */
#endif
/* Does directory end with a slash? */
/**
* Does directory end with a slash?
* @param dir Path string to check.
*
* @returns @c TRUE(1) or @c FALSE(0)
*/
static inline int fisslashdir(const char *dir)
{
if (!dir)
@@ -202,10 +242,10 @@ static inline int fisslashdir(const char *dir)
/* Compat */
#define copy_filep(src, dst) fcopyfile(src, dst)
#define pidfile_read_pid(file) pifile_read(file)
#define pidfile_read_pid(file) pidfile_read(file)
#define signal_pidfile(file, signo) pidfile_signal(file, signo)
#endif /* LITE_H_ */
#endif /* LIBITE_LITE_H_ */
#ifdef __cplusplus
}
+28 -23
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file makepath.c
* @author Joachim Wiberg
* @date 2013-2021
* @copyright ISC License
*/
#include <errno.h>
#include <libgen.h>
#include <stdarg.h>
@@ -24,12 +31,11 @@
#include "lite.h"
/**
* mkpath - Like makepath() but takes a mode_t argument
* @dir: Directory to created, relative or absolute
* @mode: A &mode_t mode to create @dir with
* makepath() but takes a mode_t argument.
* @param dir Directory to created, relative or absolute
* @param mode A &mode_t mode to create @a dir with
*
* Returns:
* POSIX OK(0) on success, otherwise -1 with @errno set.
* @returns POSIX OK(0) on success, otherwise -1 with @a errno set.
*/
int mkpath(const char *dir, mode_t mode)
{
@@ -49,15 +55,13 @@ int mkpath(const char *dir, mode_t mode)
}
/**
* fmkpath - Formatted version of mkpath()
* @mode: A &mode_t mode to create directories with
* @fmt: Formatted string to be composed into a pathname
* Formatted version of mkpath().
* @param mode A mode_t mode to create directories with
* @param fmt Formatted string to be composed into a pathname
*
* Note:
* Notice the swapped arguments, compared to mkpath()!
* @note Notice the swapped arguments, compared to mkpath()!
*
* Returns:
* POSIX OK(0) on success, otherwise -1 with @errno set.
* @returns POSIX OK(0) on success, otherwise -1 with @a errno set.
*/
int fmkpath(mode_t mode, const char *fmt, ...)
{
@@ -83,19 +87,20 @@ int fmkpath(mode_t mode, const char *fmt, ...)
}
/**
* makepath - Create all components of the specified directory.
* @dir: Directory to create.
* Create all components of the specified directory.
* @param dir Directory to create.
*
* Comment:
* It is recommended to use mkpath() over this function since it has
* the @mode argument while this function instead default ot 0777,
* which in most cases is insecure.
* @note It is strongly recommended to use mkpath() over this function
* since it has the @a mode argument while this function default to
* 0777, which in most cases is insecure.
*
* Returns:
* POSIX OK (0) on success, otherwise -1 and errno set appropriately.
* This function returns EINVAL on bad argument, or ENOMEM when it
* fails allocating temporary memory. For other error codes see the
* mkdir() syscall description.
* @returns POSIX OK (0) on success, otherwise -1 and @a errno set
* appropriately.
*
* @exception EINVAL on bad argument, or
* @exception ENOMEM when it fails allocating temporary memory.
*
* For other error codes see the mkdir(2) syscall description.
*/
int makepath(const char *dir)
{
+19 -2
View File
@@ -31,6 +31,13 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file pidfile.c
* @author NetBSD Foundation Inc.
* @date 1999
* @copyright 2-clause BSD License
*/
#include <sys/stat.h> /* utimensat() */
#include <sys/time.h> /* utimensat() on *BSD */
#include <sys/types.h>
@@ -50,8 +57,18 @@ const char *__pidfile_path = _PATH_VARRUN; /* Note: includes trailing slash '/'
const char *__pidfile_name = NULL;
extern char *__progname;
int
pidfile(const char *basename)
/**
* Create or update mtime of process PID file.
* @param basename Program name, or @c NULL, may start with '/'
*
* This function is intended to be used by UNIX daemons to save the PID of the main process
* responsible for handling signals. If @p basename is @c NULL the implicit @a __progname
* variable from the C-library is used. The @p basename may also start with '/', in which
* case it is interpreted as the absolute path to the PID file.
*
* @returns POSIX OK(0) on success, otherwise non-zero on error.
*/
int pidfile(const char *basename)
{
int save_errno;
int atexit_already;
+31 -22
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file pidfilefn.c
* @author Joachim Wiberg
* @date 2009-2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -24,16 +31,20 @@
extern char *chomp(char *str);
/**
* pidfile_read - Reads a PID value from a pidfile.
* @pidfile: File containing PID, usually in /var/run/<PROC>.pid
* Reads a PID value from a pidfile.
* @param pidfile File containing PID, usually in @c /var/run/PROCNAME.pid
*
* This function takes a @pidfile and returns the PID found therein.
* This function takes a @p pidfile and returns the PID found therein.
*
* Returns:
* On invalid @pidfile -1 and errno set to %EINVAL, when @pidfile does not exist -1
* and errno set to %ENOENT. When the pidfile is empty or when its contents cannot
* be translated this function returns zero (0), on success this function returns
* a PID value greater than one. PID 1 is reserved for the system init process.
* @returns On invalid @p pidfile, -1 with @a errno set. If the @p
* pidfile is empty, or when its contents cannot be translated, this
* function returns zero (0), on success this function returns a PID
* value greater than one.
*
* @note PID 1 is reserved for the system init process.
*
* @exception EINVAL on invalid @p pidfile, or
* @exception ENOENT when @p pidfile does not exist.
*/
pid_t pidfile_read(const char *pidfile)
{
@@ -66,15 +77,14 @@ pid_t pidfile_read(const char *pidfile)
}
/**
* pidfile_poll - Poll for the existence of a pidfile and return PID
* @pidfile: Path to pidfile to poll for
* Poll for the existence of a pidfile and return PID.
* @param pidfile Path to pidfile to poll for
*
* This function polls for the pidfile at @pidfile for at most 5 seconds
* before timing out. If the file is created within that time span the
* file is read and its PID contents returned.
* This function polls for the pidfile at @p pidfile for at most 5
* seconds before timing out. If the file is created within that time
* span the file is read and its PID contents returned.
*
* Returns:
* The PID read from @pidfile, or zero on timeout.
* @returns The PID read from @p pidfile, or zero on timeout.
*/
pid_t pidfile_poll(const char *pidfile)
{
@@ -92,15 +102,14 @@ pid_t pidfile_poll(const char *pidfile)
}
/**
* pidfile_signal - Send signal to a PID and cleanup pidfile afterwards
* @pidfile: File containing PID, usually in /var/run/<PROC>.pid
* @signal: Signal to send to PID found in @pidfile.
* Send signal to a PID and cleanup pidfile afterwards.
* @param pidfile File containing PID, usually in @c /var/run/PROCNAME.pid
* @param signal Signal to send to PID found in @p pidfile.
*
* If @signal is any of %SIGTERM, %SIGKILL, or if kill() returns -1 the
* @pidfile is removed.
* If @p signal is any of @c SIGTERM or @c SIGKILL, or if kill(2)
* returns -1, the @p pidfile is removed.
*
* Returns:
* POSIX OK(0) on success, non-zero otherwise.
* @returns POSIX OK(0) on success, non-zero otherwise.
*/
int pidfile_signal(const char *pidfile, int signal)
{
+18 -7
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file progress.c
* @author Joachim Wiberg
* @date 2012-2021
* @copyright ISC License
*/
#include <limits.h> /* INT_MAX */
#include <stdio.h>
#include <string.h>
@@ -40,21 +47,21 @@ static char spinner(char *style)
}
/**
* progress - Advanced ASCII progress bar with spinner
* @percent: Start first call with this set to 0, end with 100
* @max_width: Max width of progress bar, in total characters.
* Advanced ASCII progress bar with spinner
* @param percent Start first call with this set to 0, end with 100
* @param max_width Max width of progress bar, in total characters.
*
* This function draws an advanced ASCII progressbar at the current
* line. It always start from the first column.
*
* The progress bar will hide the cursor if started with @percent 0 and
* show it again at the end, when called with @percent 100.
* The progress bar will hide the cursor if started with @p percent 0
* and show it again at the end, when called with @p percent 100.
*
* While being called with the same percentage the spinner will spin,
* to show the user the process hasn't frozen.
*
* If the output TTY cannot interpret control characters, like \r, it is
* advised to instead used the progress_simple() function.
* If the output TTY cannot interpret control characters, like `\r`, it
* is advised to instead used the progress_simple() function.
*/
void progress(int percent, int max_width)
{
@@ -85,6 +92,10 @@ void progress(int percent, int max_width)
}
}
/**
* Alternative progress bar on systems where progress() doesn't work
* @param percent Start first call with this set to 0, end with 100
*/
void progress_simple(int percent)
{
static int last = 1;
+6 -1
View File
@@ -40,7 +40,12 @@ extern "C"
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
/**
* @file queue.h
* @author The Regents of the University of California
* @date 1991, 1993
* @copyright 3-clause BSD License
*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues and XOR simple queues.
*
+16 -2
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file reallocarray.c
* @author Otto Moerbeek
* @date 2008
* @copyright ISC License
*/
#include <sys/types.h>
#include <errno.h>
#include <stdint.h>
@@ -26,8 +33,15 @@
*/
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
reallocarray(void *optr, size_t nmemb, size_t size)
/**
* Similar to realloc() but for an array of items, like calloc()
* @param optr Pointer to old (current) array
* @param nmemb Number of elements
* @param size Size of each element, in bytes
*
* @returns A pointer to the new array, or @c NULL on error.
*/
void *reallocarray(void *optr, size_t nmemb, size_t size)
{
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) {
+24 -17
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file rsync.c
* @author Joachim Wiberg
* @date 2011-2021
* @copyright ISC License
*/
#include <errno.h>
#include <fcntl.h> /* AT_* macros */
#include <stdlib.h> /* NULL, free() */
@@ -34,31 +41,31 @@ static int set_mtime(char *fn, struct stat *st);
/**
* rsync - Synchronize contents and optionally remove non-existing backups
* @src: Source directory
* @dst: Destination directory
* @opt: An option mask of %LITE_FOPT_RSYNC_DELETE, %LITE_FOPT_KEEP_MTIME
* @filter: Optional filtering function for source directory.
* Synchronize contents and optionally remove non-existing backups
* @param src Source directory
* @param dst Destination directory
* @param opt An option mask of ::LITE_FOPT_RSYNC_DELETE, ::LITE_FOPT_KEEP_MTIME
* @param filter Optional filtering function for source directory.
*
* This is a miniature implementation of the famous rsync for local use only.
* In fact, it is not even a true rsync since it copies all files from @src
* to @dst. The @delete option is useful for creating backups, when set all
* files removed from src since last backup are pruned from the destination
* (backup) directory.
* This is a miniature implementation of the famous rsync for local use
* only. In fact, it is not even a true rsync since it copies all files
* from @p src to @p dst. The ::LITE_FOPT_RSYNC_DELETE @p opt flag is
* useful for creating backups, when set all files removed from src
* since last backup are pruned from the destination (backup) directory.
*
* The @opt parameter to rsync() is an option mask for the most common
* rsync(1) options. Previously this argument was called @delete and
* The @p opt parameter to rsync() is an option mask for the most common
* rsync(1) options. Previously this argument was called @p delete and
* to maintain backwards compatibility the value 1 is reserved:
*
* %LITE_FOPT_RSYNC_DELETE: Prune files from @dst that no longer exist in @src.
* %LITE_FOPT_RSYNC_DELETE: Prune files from @p dst that no longer exist in @p src.
* %LITE_FOPT_KEEP_MTIME: Preserve modification time
*
* The filter callback, @filter, if provided, is used to determine what
* files to include from the source directory when backing up. If a
* file is to be skipped the callback should simply return zero.
* The filter callback, @p filter, if provided, is used to determine
* what files to include from the source directory when backing up. If
* a file is to be skipped the callback should simply return zero.
*
* Returns:
* POSIX OK(0), or non-zero with @errno set on error.
* POSIX OK(0), or non-zero with @a errno set on error.
*/
int rsync(char *src, char *dst, int opt, int (*filter)(const char *file))
{
+15 -3
View File
@@ -24,13 +24,20 @@
* ==========================================================================
*/
/**
* @file strdupa.h
* @author William Ahern
* @date 2009
* @copyright MIT License
*/
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef LITE_STRDUPA_H
#define LITE_STRDUPA_H
#ifndef LIBITE_STRDUPA_H
#define LIBITE_STRDUPA_H
#if !defined(HAVE_STRDUPA)
#if defined(strdupa)
@@ -43,6 +50,11 @@ extern "C"
#include <stddef.h> /* size_t */
#include <string.h> /* memcpy(3) strlen(3) */
/**
* Duplicate string on stack.
* @param src string to duplicate
* @returns the result of memcpy(3)
*/
#define strdupa(src) (__extension__ ({ \
size_t len_ = strlen(src); \
char *dst_ = __builtin_alloca(len_ + 1); \
@@ -55,7 +67,7 @@ extern "C"
#endif /* __GNUC__ */
#endif /* !HAVE_STRDUPA */
#endif /* LITE_STRDUPA_H */
#endif /* LIBITE_STRDUPA_H */
#ifdef __cplusplus
}
+20 -6
View File
@@ -16,16 +16,30 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file strlcat.c
* @author Todd C. Miller
* @date 1998, 2015
* @copyright ISC License
*/
#include <sys/types.h>
#include <string.h>
#ifndef strlcat
/*
* Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most dsize-1 characters
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
* If retval >= dsize, truncation occurred.
/**
* Safe version of strncat() from OpenBSD
* @param dst Destination string
* @param src Source string
* @param dsize Total maximum size of @p dst
*
* Appends @p src to string @p dst of size @p dsize (unlike strncat(),
* @p dsize is the full size of @p dst, not space left). At most
* dsize-1 characters will be copied. Always NUL terminates (unless
* dsize <= strlen(dst)).
*
* @returns strlen(src) + MIN(dsize, strlen(initial dst)).
* If retval >= dsize, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t dsize)
+19 -4
View File
@@ -16,14 +16,29 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file strlcpy.c
* @author Todd C. Miller
* @date 1998, 2015
* @copyright ISC License
*/
#include <sys/types.h>
#include <string.h>
#ifndef strlcpy
/*
* Copy string src to buffer dst of size dsize. At most dsize-1
* chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= dsize, truncation occurred.
/**
* Safe version of strncpy() from OpenBSD
* @param dst Destination string
* @param src Source string
* @param dsize Total maximum size of @p dst
*
* This function copies string @p src to buffer @p dst of size @p dsize
* bytes. At most dsize-1 chars will be copied. Always NUL terminates
* (unless dsize==0).
*
* @returns strlen(src); if retval >= dsize, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t dsize)
+41 -10
View File
@@ -21,13 +21,20 @@
* THE SOFTWARE.
*/
/**
* @file strlite.h
* @author Joachim Wiberg
* @date 2008-2021
* @copyright MIT License
*/
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef LITE_STRING_H_
#define LITE_STRING_H_
#ifndef LIBITE_STRING_H_
#define LIBITE_STRING_H_
#include <stdint.h> /* uint8_t, uint16_t, uint32_t, INT32_MAX, etc. */
#include <string.h>
@@ -38,6 +45,7 @@ extern "C"
#include "strnlen.h"
#ifndef min
/** Geneirc min() macro, if a < b => a, else b */
#define min(a,b) \
({ \
__typeof__ (a) _a = (a); \
@@ -46,6 +54,7 @@ extern "C"
})
#endif
#ifndef max
/** Geneirc max() macro, if a > b => a, else b */
#define max(a,b) \
({ \
__typeof__ (a) _a = (a); \
@@ -69,7 +78,11 @@ long long strtonum (const char *numstr, long long minval, long long maxval, cons
char *strtrim (char *str);
/* Convert string to natural number (0-2147483647), returns -1 on error. */
/**
* Convert string to natural number (0-2147483647)
* @param str string to convert to number.
* @returns -1 on error.
*/
static inline int atonum(const char *str)
{
int val = -1;
@@ -84,13 +97,22 @@ static inline int atonum(const char *str)
return val;
}
/* Validate string, non NULL and not zero length */
static inline int string_valid(const char *s)
/**
* Validate string, non NULL and not zero length
* @param str string to validate
* @returns @c TRUE(1) or @c FALSE(0).
*/
static inline int string_valid(const char *str)
{
return s && strlen(s);
return str && strlen(str);
}
/* Relaxed comparison, e.g., sys_string_match("small", "smaller") => TRUE */
/**
* Relaxed comparison, e.g., sys_string_match("small", "smaller") => TRUE
* @param a first string
* @param b second string
* @returns @c TRUE(1) or @c FALSE(0).
*/
static inline int string_match(const char *a, const char *b)
{
size_t min = MIN(strlen(a), strlen(b));
@@ -98,21 +120,30 @@ static inline int string_match(const char *a, const char *b)
return !strncasecmp(a, b, min);
}
/* Strict comparison, e.g., sys_string_match("small", "smaller") => FALSE */
/**
* Strict comparison, e.g., sys_string_match("small", "smaller") => FALSE
* @param a first string
* @param b second string
* @returns @c TRUE(1) or @c FALSE(0).
*/
static inline int string_compare(const char *a, const char *b)
{
return strlen(a) == strlen(b) && !strcmp(a, b);
}
/* Strict comparison, like sys_string_compare(), but case insensitive,
/**
* Strict comparison, like sys_string_compare(), but case insensitive,
* e.g., sys_string_match("small", "SmAlL") => TRUE
* @param a first string
* @param b second string
* @returns @c TRUE(1) or @c FALSE(0).
*/
static inline int string_case_compare(const char *a, const char *b)
{
return strlen(a) == strlen(b) && !strcasecmp(a, b);
}
#endif /* LITE_STRING_H_ */
#endif /* LIBITE_STRING_H_ */
#ifdef __cplusplus
}
+24 -19
View File
@@ -15,24 +15,30 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file strmatch.c
* @author Joachim Wiberg
* @date 2009-2021
* @copyright ISC License
*/
#include <errno.h>
#include <string.h>
/**
* strnmatch - Finds matching strings from a finite list
* @str: String to look for
* @list: List of strings to search.
* @num: Number of entries in @list.
* Finds matching strings from a finite list
* @param str String to look for
* @param list List of strings to search.
* @param num Number of entries in @p list.
*
* This function searches the @list of strings for @str. If a (partial) match
* is found it returns the index in the @list.
* This function searches the @p list of strings for @p str. If a
* (partial) match is found it returns the index in the @p list.
*
* Very similar in function to strmatch(), but works for sets of strings that
* are not %NULL terminated.
* Very similar in function to strmatch(), but works for sets of strings
* that are not @c NUL terminated.
*
* Returns:
* -1 on error, otherwise the index to the matching string.
* @returns -1 on error, otherwise the index to the matching string.
*/
int strnmatch(const char *str, const char **list, size_t num)
{
@@ -53,18 +59,17 @@ int strnmatch(const char *str, const char **list, size_t num)
}
/**
* strmatch - Finds matching strings from a list
* @str: String to look for
* @list: %NULL terminated list of strings to search.
* Finds matching strings from a list
* @param str String to look for.
* @param list NUL terminated list of strings to search.
*
* This function searches the @list of strings for @str. If a (partial) match
* is found it returns the index in the @list.
* This function searches the @p list of strings for @p str. If a
* (partial) match is found it returns the index in the @p list.
*
* Please note, the @list MUST be terminated by a %NULL element. If that is
* not possible for you, we recommend using strnmatch() instead.
* Please note, the @p list MUST be terminated by a NUL element. If
* that is not possible, we recommend using strnmatch() instead.
*
* Returns:
* -1 on error, otherwise the index to the matching string.
* @returns -1 on error, otherwise the index to the matching string.
*/
int strmatch(const char *str, const char **list)
{
+16 -3
View File
@@ -24,13 +24,20 @@
* ==========================================================================
*/
/**
* @file strndupa.h
* @author William Ahern
* @date 2009
* @copyright MIT License
*/
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef LITE_STRNDUPA_H_
#define LITE_STRNDUPA_H_
#ifndef LIBITE_STRNDUPA_H_
#define LIBITE_STRNDUPA_H_
#if !defined(HAVE_STRNDUPA)
#if defined(strndupa)
@@ -44,6 +51,12 @@ extern "C"
#include <string.h> /* memcpy(3) */
#include "strnlen.h"
/**
* Duplicate part of string on stack
* @param src string to duplicate
* @param lim number of bytes to dupliate
* @returns the result of memcpy(3)
*/
#define strndupa(src, lim) (__extension__ ({ \
size_t len_ = strnlen(src, lim); \
char *dst_ = __builtin_alloca(len_ + 1); \
@@ -56,7 +69,7 @@ extern "C"
#endif /* __GNUC__ */
#endif /* !HAVE_STRNDUPA */
#endif /* GNU_STRING_STRNDUPA_H */
#endif /* LIBITE_STRNDUPA_H */
#ifdef __cplusplus
}
+18 -5
View File
@@ -15,13 +15,20 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file strnlen.h
* @author Joachim Wiberg
* @date 2016-2021
* @copyright ISC License
*/
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef LITE_STRNLEN_H_
#define LITE_STRNLEN_H_
#ifndef LIBITE_STRNLEN_H_
#define LIBITE_STRNLEN_H_
#if !defined(HAVE_STRNLEN)
#if defined(strnlen)
@@ -32,20 +39,26 @@ extern "C"
#if !HAVE_STRNLEN
#include <stddef.h> /* size_t */
#define strnlen(str, lim) xstrnlen(str, lim)
#define strnlen(str, lim) xstrnlen(str, lim) /**< Wrapper for xstrnlen() */
/**
* Reimplementation of GLIBC strnlen()
* @param str string to return length of
* @param lim max number of bytes to read
* @returns length of @p str in bytes, but at most @lim bytes.
*/
static inline size_t xstrnlen(const char *str, size_t lim)
{
size_t i = 0;
while (str[i] && i < lim)
while (i < lim && str[i])
i++;
return i;
}
#endif
#endif /* LITE_STRNLEN_H_ */
#endif /* LIBITE_STRNLEN_H_ */
#ifdef __cplusplus
}
+42 -6
View File
@@ -17,24 +17,60 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file strtonum.c
* @author Ted Unangst
* @author Todd Miller
* @date 2004
* @copyright ISC License
*/
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#ifndef strtonum
#define INVALID 1
#define TOOSMALL 2
#define TOOLARGE 3
#define INVALID 1 /**< internal */
#define TOOSMALL 2 /**< internal */
#define TOOLARGE 3 /**< internal */
#ifndef LLONG_MAX
# define LLONG_MAX 0x7fffffffffffffffLL
# define LLONG_MAX 0x7fffffffffffffffLL /**< internal */
#endif
#ifndef LLONG_MIN
# define LLONG_MIN (-0x7fffffffffffffffLL - 1)
# define LLONG_MIN (-0x7fffffffffffffffLL - 1) /**< internal */
#endif
/**
* Reliably convert string value to an integer
* @param numstr String to convert to a number
* @param minval Lower bound to check number against
* @param maxval Upper bound to check number against
* @param errstrp Pointer to error string
*
* This function converts the string in @p numstr to a long long value.
* The function was designed to facilitate safe, robust programming and
* overcome the shortcomings of the atoi(3) and strtol(3) family of
* interfaces.
*
* The string may begin with an arbitrary amount of whitespace (as
* determined by isspace(3)) followed by a single optional ‘+’ or ‘-’
* sign.
*
* The remainder of the string is converted to a long long value
* according to base 10.
*
* The value obtained is then checked against the provided @p minval and
* @p maxval bounds. If @p errstrp is non-NULL, strtonum() stores an
* error string in @p *errstrp indicating the failure.
*
* @returns The result of the conversion, unless the value would exceed
* the provided bounds or is invalid. On error, 0 is returned, @a errno
* is set, and @p errstrp points to an error message. @p *errstr* is set
* to @c NULL on success; this fact can be used to differentiate a
* successful return of 0 from an error.
*/
long long
strtonum(const char *numstr, long long minval, long long maxval,
const char **errstrp)
+13 -6
View File
@@ -16,6 +16,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file strtrim.c
* @author Mattias Walström
* @author Joachim Wiberg
* @date 2014,2021
* @copyright ISC License
*/
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
@@ -23,16 +31,15 @@
#include "lite.h"
/**
* strtrim - Strip leading and trailing whitespace from a string
* @str: The string to trim
* Strip leading and trailing whitespace from a string
* @param str The string to trim
*
* Trims a string from any leading and trailing white-space, returns the
* trimmed result in the same buffer.
*
* Returns:
* If @str is a valid, non-NULL, string this function returns the same
* string stripped from whitespace. This function only returns %NULL
* if @str itself is %NULL.
* @returns If @p str is a valid, non-NULL string this function returns
* the same string stripped from whitespace. This function only returns
* @c NULL if @p str itself is @c NULL.
*/
char *strtrim(char *str)
{
+20
View File
@@ -15,12 +15,32 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file systemf.c
* @author Joachim Wiberg
* @date 2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
/**
* Like system(), but takes a formatted string as argument.
* @param fmt printf style format list to command to run
*
* This system() wrapper greatly simplifies operations that usually
* consist of composing a command from parts into a dynamic buffer
* before calling it. The return value from system() is also parsed,
* checking for proper exit and signals.
*
* @returns If the command exits normally, the return code of the command
* is returned. Otherwise, if the command is signalled, the return code
* is -1 and @a errno is set to @c EINTR.
*/
int systemf(const char *fmt, ...)
{
va_list ap;
+41 -22
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file telnet.c
* @author Joachim Wiberg
* @date 2010-2021
* @copyright ISC License
*/
#include <errno.h>
#include <poll.h>
#include <unistd.h>
@@ -33,12 +40,19 @@
# define TELL(fmt, args...)
#endif
/** @private for internal use only */
struct sdbuf {
int sd;
int sd;
char *buf;
} sdbuf;
};
/* Open telnet connection to @addr:@port and connect. */
/**
* Open telnet connection to addr:port and connect.
* @param addr Integer encoded IPv4 address in network byte order
* @param port Internet port number in network byte order
*
* @returns An @ref sdbuf_t socket buffer context.
*/
sdbuf_t *telnet_open(int addr, short port)
{
struct sockaddr_in *sin;
@@ -93,6 +107,12 @@ sdbuf_t *telnet_open(int addr, short port)
return ctx;
}
/**
* Close a telnet session previously opened with telnet_open()
* @param ctx An @ref sdbuf_t socket buffer context
*
* @returns Always returns POSIX OK(0).
*/
int telnet_close(sdbuf_t *ctx)
{
free(ctx->buf);
@@ -137,20 +157,19 @@ static int wait_substr(sdbuf_t *ctx, char *str)
}
/**
* telnet_expect - Poor man's telnet expect
* @ctx: Telnet session context from telnet_open()
* @script: %NULL terminated list of expect and response strings
* @output: Optional output from session
* Poor man's telnet expect
* @param ctx Telnet session context from telnet_open()
* @param script @c NULL terminated list of expect and response strings
* @param output Optional output from session
*
* Issues @script sequence on telnet session specified in @ctx, with
* optional @output from session.
* Issues @p script sequence on telnet session specified in @p ctx, with
* optional @p output from session.
*
* The @script consists of strings of expect and response pairs. For
* The @p script consists of strings of expect and response pairs. For
* example, expect "ogin: " followed by response "root\n", expect
* "assword: "with response "secret\n", concluded by %NULL.
* "assword: "with response "secret\n", concluded by @c NULL.
*
* Returns:
* POSIX OK(0) or non-zero on error.
* @returns POSIX OK(0) or non-zero on error.
*/
int telnet_expect(sdbuf_t *ctx, char *script[], FILE *output)
{
@@ -258,20 +277,20 @@ int telnet_expect(sdbuf_t *ctx, char *script[], FILE *output)
}
/**
* telnet_session - Very simple expect-like implementation for telnet.
* @addr: Must be in network byte order, use htonl().
* @port: IP port to connect to, use htons().
* @script: Expect like script of paired 'expect', 'response' strings.
* @output: A &FILE pointer to a tmpfile() for output from the last command.
* Very simple expect-like implementation for telnet.
* @param addr Integer encoded IPv4 address, in network byte order, use htonl().
* @param port Internet port to connect to, in network byte order, use htons().
* @param script Expect like script of paired 'expect', 'response' strings.
* @param output A FILE pointer to a tempfile() for output from the last command.
*
* This is a very simple expect-like implementation for querying and
* operating daemons remotely over telnet.
*
* The @script is a query-response type of list of strings leading up to
* a final command, which output is then written to the given @output file.
* The @p script is a query-response type of list of strings leading up
* to a final command, which output is then written to the given @p
* output file.
*
* Returns:
* POSIX OK(0), or non-zero with errno set on error.
* @returns POSIX OK(0), or non-zero with @a errno set on error.
*/
int telnet_session(int addr, short port, char *script[], FILE *output)
{
+36 -9
View File
@@ -15,23 +15,46 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file tempfile.c
* @author Joachim Wiberg
* @date 2015-2021
* @copyright ISC License
*/
#include <errno.h>
#include <paths.h>
#include <fcntl.h> /* O_TMPFILE requires -D_GNU_SOURCE */
#include <stdio.h> /* fdopen() */
#include <stdlib.h> /* mkostemp() */
#include <sys/stat.h> /* umask() */
static FILE *fallback(void)
{
char nm[15] = _PATH_TMP "XXXXXXXX";
int fd;
fd = mkostemp(nm, O_CLOEXEC);
if (-1 == fd)
return NULL;
return fdopen(fd, "w+");
}
/**
* tempfile - A secure tmpfile() replacement
* A secure tmpfile() replacement
*
* This is the secure replacement for tmpfile() that does not exist in
* GLIBC. The function uses the Linux specific %O_TMPFILE and %O_EXCL
* for security. When the %FILE is fclose()'ed the file contents is
* lost. The file is hidden in the %_PATH_TMP directory on the system.
* GLIBC. It uses the Linux specific @c O_TMPFILE and @c O_EXCL to hide
* the filename. When the @c FILE is fclose()'ed, the file contents is
* lost. The file is hidden in the @c _PATH_TMP ("/tmp") directory in
* the system.
*
* This function requires Linux 3.11, or later, due to %O_TMPFILE.
* This function requires Linux 3.11, or later, due to @c O_TMPFILE.
* Not all file systems support hidden inodes, in which case this
* function defaults to call tmpfile() as a fallback.
*
* Returns:
* An open %FILE pointer, or %NULL on error.
* @returns An open @c FILE pointer, or @c NULL on error.
*/
FILE *tempfile(void)
{
@@ -42,12 +65,16 @@ FILE *tempfile(void)
oldmask = umask(0077);
fd = open(_PATH_TMP, O_TMPFILE | O_RDWR | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR);
umask(oldmask);
if (-1 == fd)
if (-1 == fd) {
if (errno == EOPNOTSUPP)
return fallback();
return NULL;
}
return fdopen(fd, "w+");
#else
return tmpfile(); /* Fallback on older GLIBC/Linux and actual UNIX systems */
return fallback();
#endif
}
+11 -5
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file touchf.c
* @author Joachim Wiberg
* @date 2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
@@ -24,16 +31,15 @@
#include "lite.h"
/**
* touchf - Like touch() but with formatted string support
* @fmt: Formatted string to be composed into a pathname
* Like touch() but with formatted string support
* @param fmt Formatted string to be composed into a pathname
*
* This is a wrapper for the touch() function in lite.h, lessening the
* burden of having to compose the filename from parts in a seprate
* buffer.
*
* Returns:
* Upon successful completion touchf() returns POSIX OK(0), otherwise,
* -1 is returned and errno is set to indicate the error.
* @returns Upon successful completion touchf() returns POSIX OK(0),
* otherwise, -1 is returned and @a errno is set to indicate error.
*/
int touchf(const char *fmt, ...)
{
+6 -1
View File
@@ -32,7 +32,12 @@ extern "C"
#ifndef _SYS_TREE_H_
#define _SYS_TREE_H_
/*
/**
* @file tree.h
* @author Niels Provos
* @date 2002
* @copyright 2-clause BSD License
*
* This file defines data structures for different types of trees:
* splay trees and red-black trees.
*
+12 -6
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file truncatef.c
* @author Joachim Wiberg
* @date 2021
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
@@ -22,16 +29,15 @@
#include <unistd.h>
/**
* truncatef - Truncate a file based on the formatted string
* @length: Size in bytes to truncate file to, zero to empty it
* @fmt: Formatted string to be composed into a pathname
* Truncate a file based on the formatted string
* @param length Size in bytes to truncate file to, zero to empty it
* @param fmt Formatted string to be composed into a pathname
*
* This is an extension to the truncate() family, lessening the burden
* of having to compose the filename from parts in a seprate buffer.
*
* Returns:
* Upon successful completion truncate() returns POSIX OK(0), otherwise,
* -1 is returned and errno is set to indicate the error.
* @returns Upon successful completion truncate() returns POSIX OK(0),
* otherwise, -1 is returned and @a errno is set to indicate error.
*/
int truncatef(off_t length, const char *fmt, ...)
{
+17 -4
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file which.c
* @author Joachim Wiberg
* @date 2017-2021
* @copyright ISC License
*/
#include <ctype.h>
#include <errno.h>
#include <stdio.h> /* snprintf() */
@@ -38,8 +45,11 @@ static char *strip_args(char *path)
return path;
}
/*
* Like which(1), returns a malloc'ed path to cmd on success, or NULL
/**
* Like which(1), or `command -v foo`
* @param cmd Command to look for in $PATH
*
* @returns A malloc()'ed path to @a cmd on success, or @c NULL.
*/
char *which(const char *cmd)
{
@@ -103,8 +113,11 @@ char *which(const char *cmd)
return NULL;
}
/*
* Like which(), above, but only answers TRUE(1)/FALSE(0)
/**
* Predicate variant of which()
* @param cmd Command to look for in $PATH
*
* @returns @c TRUE(1) or @c FALSE(0) if @p cmd exists in $PATH.
*/
int whichp(const char *cmd)
{
+10 -4
View File
@@ -15,6 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file yorn.c
* @author Joachim Wiberg
* @date 2009-2021
* @copyright ISC License
*/
#include <stdio.h>
#include <stdio_ext.h> /* __fpurge() */
#include <stdarg.h>
@@ -56,14 +63,13 @@ static char rawgetch(void)
}
/**
* yorn - Pose a a Yes or No question and return answer
* @fmt: Standard printf() style argument(s).
* Pose a a Yes or No question and return answer
* @param fmt Standard printf() style argument(s).
*
* This function prints the given question on screen, waits for user
* input in the form of yes or no.
*
* Returns:
* True(1) or False(0). True if the answer is yes.
* @returns TRUE(1) or FALSE(0). True if the answer is yes.
*/
int yorn(const char *fmt, ...)
{
File renamed without changes.
+11 -11
View File
@@ -1,8 +1,14 @@
EXTRA_DIST = check.h \
data/fexist/dir/.placeholder data/fexist/executable data/fexist/link \
data/fexist/regular data/lfile/fstab data/lfile/group data/lfile/passwd \
data/lfile/protocols data/lfile/services data/which/executable \
data/which/executable-link data/which/regular
# Ignore warnings about unused result, in e.g. write()
AM_CFLAGS = -W -Wall -Wextra -Wno-unused-result
AM_CPPFLAGS = -D_GNU_SOURCE
AM_LDFLAGS = -L../src/ ../src/libite.la -static
EXTRA_DIST = check.h data/fexist/dir/.placeholder data/fexist/executable
EXTRA_DIST += data/fexist/link data/fexist/regular data/lfile/fstab
EXTRA_DIST += data/lfile/group data/lfile/passwd data/lfile/protocols
EXTRA_DIST += data/lfile/services data/which/executable
EXTRA_DIST += data/which/executable-link data/which/regular
CLEANFILES = *~ *.trs *.log
TESTS_ENVIRONMENT = ([ -d data ] || ln -sf $(srcdir)/data) &&
@@ -33,9 +39,3 @@ TESTS += which
TESTS += yorn
check_PROGRAMS = $(TESTS)
# Ignore warnings about unused result, in e.g. write()
CFLAGS += -Wno-unused-result
CPPFLAGS += -D_GNU_SOURCE
LDADD = -L../src/ ../src/libite.la
LDFLAGS += -static
+3 -3
View File
@@ -1,5 +1,5 @@
#ifndef LITE_TESTS_CHECK_H_
#define LITE_TESTS_CHECK_H_
#ifndef LIBLITE_TESTS_CHECK_H_
#define LIBLITE_TESTS_CHECK_H_
#include <stdarg.h>
#include <stdlib.h>
@@ -78,4 +78,4 @@ static inline char *timespec2str(struct timespec *ts, char *buf, size_t len)
return buf;
}
#endif /* LITE_TESTS_CHECK_H_ */
#endif /* LIBLITE_TESTS_CHECK_H_ */
View File
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
File renamed without changes.
View File
File renamed without changes.
File renamed without changes.
+4
View File
@@ -17,12 +17,16 @@ static struct stat before, after;
static void sigterm_handler(int signo)
{
(void)signo;
PRINT("Exiting ...\n");
remove(PIDFILE);
}
static void sigalrm_handler(int signo)
{
(void)signo;
PRINT("Calling pidfile(%s)\n", pidfile_arg ?: "NULL");
if (pidfile(pidfile_arg))
err(1, "failed creating1 %s", pidfile_arg);
File renamed without changes.
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
File renamed without changes.
+12
View File
@@ -1,6 +1,16 @@
#include <err.h>
#include "check.h"
/*
* Depending on the system and default shell, `kill -QUIT $$` (below)
* may leave a core file, so we need to clean that up here to prevent
* the distcleancheck target from failing.
*/
static void cleanup(void)
{
remove("core");
}
int main(void)
{
struct { char *cmd; int rc; } list[] = {
@@ -12,6 +22,8 @@ int main(void)
{ "kill -INT $$", -1 }
};
atexit(cleanup);
for (size_t i = 0; i < NELEMS(list); i++) {
int rc;
+8 -5
View File
@@ -13,24 +13,27 @@
int main(void)
{
int ret;
FILE *fp;
char buf[80] = "";
FILE *fp;
printf("Before tempfile():\n");
ret = system("ls -lrt " _PATH_TMP " | tail -3");
system("ls -lrt " _PATH_TMP " | tail -3");
fflush(stdout);
fp = tempfile();
if (fp == NULL)
fprintf(stderr, "Failed tempfile(), errno %d: %s", errno, strerror(errno));
fail_unless(fp != NULL);
ret = fputs(READBACK, fp);
fputs(READBACK, fp);
rewind(fp);
if (fgets(buf, sizeof(buf), fp))
fprintf(stderr, "\nRead-back from tempfile: %s", buf);
fail_unless(!strcmp(buf, READBACK));
printf("\nAfter tempfile(), should be same list:\n");
ret = system("ls -lrt " _PATH_TMP " | tail -3");
system("ls -lrt " _PATH_TMP " | tail -3");
fflush(stdout);
return fclose(fp);
}
View File
File renamed without changes.
+7 -7
View File
@@ -11,13 +11,13 @@ int main(void)
int result = 0;
size_t i;
struct tc test[] = {
{ "executable", 1 },
{ "executable -h", 1 },
{ "executable-link", 1 },
{ "regular", 0 },
{ "ls", 1 },
{ "/usr/bin/which", 1 },
{ NULL, 0 }
{ "executable", 1, 0 },
{ "executable -h", 1, 0 },
{ "executable-link", 1, 0 },
{ "regular", 0, 0 },
{ "ls", 1, 0 },
{ "/usr/bin/which", 1, 0 },
{ NULL, 0, 0 }
};
setenv("PATH", "data/which:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin", 1);
+1 -1
View File
@@ -4,7 +4,7 @@
#include "check.h"
int main(int argc, char *argv[])
int main(void)
{
int chan[2];
int status;