Compare commits

...
41 Commits
Author SHA1 Message Date
Joachim Wiberg 960e7f69ed Update changelog and bump version for v2.6.1 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-15 10:22:36 +02:00
Joachim Wiberg 68bc83f08f FTBFS uClibc and musl libc, lite.h missing stdarg.h include
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-15 10:21:30 +02:00
Joachim Wiberg 986d29caf0 m4: sync with latest ax_prog_doxygen.m4
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-15 10:18:33 +02:00
Joachim Wiberg 2d9f8f595d Update ChangeLog and bump version to v2.6.0 GA
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 16:59:24 +02:00
Joachim Wiberg 3f8ad99f1f Fix varargs bug/usage, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:47:59 +02:00
Joachim Wiberg 63e25ecae4 .github: use new syntax for setting variables
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:47:43 +02:00
Joachim Wiberg 6c53ee819b test: adjust times again
Running the tests in a Debian container seem to be taking way too long.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:26:08 +02:00
Joachim Wiberg da21e02be0 Update ChangeLog diffs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:19:13 +02:00
Joachim Wiberg c33500c372 .github: import release job from Mg project
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:17:53 +02:00
Joachim Wiberg bed65c84e6 .github: bump action versions, node12 deprecated
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:17:27 +02:00
Joachim Wiberg c4f262b721 debian: prepare new release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:17:14 +02:00
Joachim Wiberg 563b387ec7 test: increase delay waiting for background job in Debian container
GitHub action fails, probably due to too short wait delay.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:11:51 +02:00
Joachim Wiberg b93d74c065 Update ChangeLog and bump version for v2.6.0-rc1
Bump ABI: 5.3.2 -> 5.4.0

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 12:00:04 +02:00
Joachim Wiberg c1f7bc2bbb Update copyright years
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 11:56:26 +02:00
Joachim Wiberg 99f644b512 doc: document new procfile functions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 11:48:37 +02:00
Joachim Wiberg 92bb0ca399 runbg: new helper function inspired by the Infix project
The runbg() function is a delayed execvp() that has double-forked to the
background (to not create zombies).  It is useful for running commands
in the background for APIs that need to return a reply, e.g. a NETCONF
RPC to reboot the system.

Compared to the original in Infix, this version double forks to reparent
itself to PID 1 (init), closes all open files, including stdio.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 11:00:09 +02:00
Joachim Wiberg 921afdecb4 Minor, indent
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 10:49:25 +02:00
Joachim Wiberg 47b02df823 Minor, spellcheck
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-17 10:49:13 +02:00
Joachim Wiberg 4dd14dac42 New helper functions to read/write /proc and /sys style files
From the Infix project.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-11 13:19:05 +02:00
Joachim Wiberg 97a3d43e9c Reminder
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-11 12:47:49 +02:00
Joachim Wiberg 784a667584 New helper function, fexistf(), made for the Infix project
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-11 12:18:45 +02:00
Joachim Wiberg 1f6ff90d9e New helper function, vfopenf(), inspired by the Infix project
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-11 12:16:58 +02:00
Joachim Wiberg 9eb847e56c New helper function, popenf(), from the Infix project
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-11 12:03:24 +02:00
Joachim Wiberg 55272c13f7 Start new devel cycle for v2.6.0 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-06-11 11:38:01 +02:00
Joachim Wiberg 34097d33b6 Update changelog and bump version for v2.5.3 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-08 07:05:58 +02:00
Joachim Wiberg 311288eec9 test: major refactor and cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-08 06:51:25 +02:00
Joachim Wiberg 63cf8867c5 test: refactor, each test in separate func
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-08 06:00:47 +02:00
Joachim Wiberg ac7b4194cf Fix copyfile() regression introduced in 4e9b5c13
Caught in release cycle.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-08 05:55:48 +02:00
Joachim Wiberg e44aaa4fd5 test: slight refactor to add diff -q A B check to fcopyfile()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-08 05:55:48 +02:00
Joachim Wiberg 97cb2cb87c test: reproduce copyfile() off by one regression
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-08 05:55:39 +02:00
Joachim Wiberg 837c3f23be Prepare for v2.5.3 bug fix release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-02 22:20:03 +02:00
Joachim Wiberg 4e9b5c13c1 copyfile: allow copying empty files to non-existing destination dirs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-02 22:17:47 +02:00
Joachim Wiberg d61b847e55 rsync: fix check for missing dst when dst is a directory
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-02 22:17:09 +02:00
Joachim Wiberg 90fdcdeb39 rsync: fix return value when copying a single file
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-02 22:16:50 +02:00
Joachim Wiberg e36ac8f462 test: finalize rsync unit test to reproduce bugs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-04-02 22:16:21 +02:00
Joachim Wiberg eb3bb94cfa Update changelog and bump version for v2.5.2 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 14:19:11 +02:00
Joachim Wiberg 11b9c88732 Add printf format attribute to all vararg functions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 14:11:31 +02:00
Joachim Wiberg 11d4aafce1 Merge pull request #20 from yangfl/upstream
Fix for some non-linux
2022-01-27 11:34:50 +01:00
yangfl 5cdc5736f3 Replace mknod() with creat()
For mknod(), mode must be S_IFIFO otherwise the behaviour is unspecified
according to SUS, and apparently Debian/kFreeBSD is in the hater list.
2022-01-27 00:11:00 +08:00
yangfl 059bfd7806 test: use sleep() for mtime delay
For filesystems without high-resolution time support, an usleep() is too short
to alter mtime. Though 1s is quite safe, sleep for 2s in case it gets awaken
right within that second.
2022-01-26 23:57:27 +08:00
yangfl 0cda6339a4 Fix fisdir sigfault on Hurd
Apparently Hurd's stat() does not like NULL and will sigfault, this patch takes
care of it.
2022-01-26 02:11:08 +08:00
27 changed files with 930 additions and 181 deletions

No files matched your search

+3 -3
View File
@@ -28,7 +28,7 @@ jobs:
run: |
sudo apt-get -y update
sudo apt-get -y install tree doxygen
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Configure
run: |
./autogen.sh
@@ -44,7 +44,7 @@ jobs:
run: |
make check || (cat test/test-suite.log; false)
- name: Upload Test Results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: libite-test-${{ matrix.compiler }}
path: test/*
@@ -55,7 +55,7 @@ jobs:
env:
MAKEFLAGS: -j3
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Installing dependencies
run: |
apt-get update
+4 -6
View File
@@ -15,7 +15,7 @@ jobs:
coverity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Fetch latest Coverity Scan MD5
id: var
env:
@@ -24,10 +24,8 @@ jobs:
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
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v3
id: cache
with:
path: coverity-latest.tar.gz
@@ -76,7 +74,7 @@ jobs:
--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
uses: actions/upload-artifact@v3
with:
name: coverity-build.log
path: cov-int/build-log.txt
+12 -37
View File
@@ -7,38 +7,11 @@ on:
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
- uses: actions/checkout@v3
- name: Installing dependencies ...
run: |
sudo apt-get -y update
@@ -46,17 +19,19 @@ jobs:
- name: Creating Makefiles ...
run: |
./autogen.sh
./configure
./configure --prefix=
- name: Build release ...
run: |
make release || (cat test/test-suite.log; false)
ls -lF ../
make release
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 }}
- name: Extract ChangeLog entry ...
run: |
awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \
|head -n -1 > release.md
cat release.md
- uses: ncipollo/release-action@v1
with:
releaseId: ${{ needs.release.outputs.release_id }}
args: artifacts/*
name: Libite (-lite) ${{ github.ref_name }}
bodyFile: "release.md"
artifacts: "artifacts/*"
+53 -1
View File
@@ -4,6 +4,54 @@ Change Log
All notable changes to the project are documented in this file.
[v2.6.1][] - 2023-10-15
-----------------------
### Fixes
- FTBFS uClibc and musl libc, `lite.h` missing `stdarg.h` include
[v2.6.0][] - 2023-09-17
-----------------------
### Changes
- New APIs from the [Infix Project](https://github.com/kernelkit/infix):
- `fexistf()`
- `vfopenf()`
- `popenf()`
- `vreadsnf()`, `readsnf()`, `writesf()`
- `vreadllf()`, `readllf()`, `readdf()`
- `writellf()`, `writedf()`
### Fixes
- Spellchecking of API docs
[v2.5.3][] - 2023-04-08
-----------------------
### Changes
- Refactor `copyfile()` unit test and verify number of bytes copied
- Add missing `rsync()` unit test to ensure proper function
### Fixes
- `rsync()` does not copy single files correctly
- `copyfile()` does not handle empty source files correctly (error)
- `copyfile()` does not properly create destination dir
[v2.5.2][] - 2022-04-17
-----------------------
### Changes
- Add printf format attribute hint to all vararg functions. This will
help users of these functions by telling CC what to look for
### Fixes
- Fix `fisdir()` segfault on GNU/Hurd
- Fix `touch)` on Debian/kFreeBSD, use `creat()` instad of `mknod()`
[v2.5.1][] - 2021-12-02
-----------------------
@@ -463,7 +511,11 @@ problems this may cause!
Initial extraction of frog DNA from [Finit][]. See [README][] for API details.
[UNRELEASED]: https://github.com/troglobit/libite/compare/v2.5.1...HEAD
[UNRELEASED]: https://github.com/troglobit/libite/compare/v2.6.1...HEAD
[v2.6.1]: https://github.com/troglobit/libite/compare/v2.6.0...v2.6.1
[v2.6.0]: https://github.com/troglobit/libite/compare/v2.5.3...v2.6.0
[v2.5.3]: https://github.com/troglobit/libite/compare/v2.5.2...v2.5.3
[v2.5.2]: https://github.com/troglobit/libite/compare/v2.5.1...v2.5.2
[v2.5.1]: https://github.com/troglobit/libite/compare/v2.5.0...v2.5.1
[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
+1 -1
View File
@@ -1,5 +1,5 @@
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
Copyright (c) 2008-2023 Joachim Wiberg <troglobit@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+1
View File
@@ -0,0 +1 @@
* TODO Write tests for new APIs
+1 -1
View File
@@ -1,4 +1,4 @@
AC_INIT(libite, 2.5.1, https://github.com/troglobit/libite/issues)
AC_INIT(libite, 2.6.1, https://github.com/troglobit/libite/issues)
AC_CONFIG_AUX_DIR(aux)
AM_INIT_AUTOMAKE([1.11 foreign dist-xz])
AM_SILENT_RULES([yes])
+24
View File
@@ -1,3 +1,27 @@
libite (2.6.0) stable; urgency=medium
* New APIs from Infix Project:
- fexistf()
- vfopenf()
- popenf()
- vreadsnf(), readsnf(), writesf()
- vreadllf(), readllf(), readdf()
- writellf(), writedf()
* Spellchecking of API docs
-- Joachim Wiberg <troglobit@gmail.com> Sun, 17 Sep 2023 12:16:47 +0200
libite (2.5.3) stable; urgency=medium
* rsync() does not copy single files correctly
* copyfile() does not handle empty source files correctly (error)
* copyfile() does not properly create destination dir
* Add printf format attribute hint to all vararg functions
* Fix fisdir() segfault on GNU/Hurd
* Fix touch() on Debian/kFreeBSD, use creat() instad of mknod()
-- Joachim Wiberg <troglobit@gmail.com> Sat, 08 Apr 2023 07:04:00 +0200
libite (2.5.1) stable; urgency=medium
* Use dh_link(1) to install `/usr/include/lite -> libite/`.
+84 -1
View File
@@ -124,7 +124,7 @@ Generic Functions
Check for the existence of a directory, returns True(1) or False(0).
- `fopenf(mode, fmt, ...)`
- `fopenf(mode, fmt, ...)` and `vfopenf(mode, fmt, ap)`
Like `fopen()`, but takes a formatted string as argument. This
greatly simplifies operations that usually consist of composing a
@@ -249,6 +249,19 @@ Generic Functions
`delete`, it is now called `opt`. The APIs are 100% compatible if the
value `1` was used.
- `runbg(cmd, delay)`
Run a command in the background, after delay microseconds, essentially
a background `execvp()` with a delay. The function employs double-fork
to prevent zombies and closes all open files, including stdio.
```C
char *cmd[] = { "sh", "-c", "echo 'hej' >/tmp/foo", NULL};
runbg(cmd, 200000); /* Create /tmp/foo after 200 millisec */
/* Execution continues here immediately */
```
- `strmatch(str, list)`, `strnmatch(str, list, len)`
Find matching string in an array of strings. Returns index in array on
@@ -307,6 +320,76 @@ Generic Functions
yes (both `y` and `Y` are handled) and `FALSE` for everything else.
Procfile Functions
------------------
These functions can be used to simplify access to data in `/proc` and
`/sys` on a Linux system.
### String Functions
- `readsnf(line, len, fmt, ...)`
Read first line from a file composed from `fmt`, with optional args.
At most `len` bytes from the file are stored in `line`.
On success this function returns `line` with any trailing newlines
`chomp()`ed off. On error `NULL` is returned.
- `vreadsnf(line, len, fmt, ap)`
Similar to `readsnf()` but takes a `va_list` argument instead.
- `writesf(str, mode, fmt, ...)`
Write the string buffer `str`, with an additional newline, to a file
composed from `fmt`, with optional args. The file is opened with the
given `mode`, e.g. "w+", which allows for both replacing and appending
file content.
The function returns POSIX OK(0) on success or -1 on failure with the
`errno` variable set to a value from either `fopen()` or `fclose()`.
### Integer Functions
Read and write 32-bit and 64-bit signed values from/to files.
- `vreadllf(value, fmt, ap)` and `readllf(value, fmt, ...)`
Only the first line is read. If the line has newline that is stripped
before calling `strtoll()` on the line. The arguments to the latter
function is such that it can convert also from a hexadecimal value.
This function may fail and return -1 on opening the file, reading a
line, or if the `strtoll()` function fails. All of which set the
`errno` variable. Otherwise this function return POSIX OK(0).
- `readdf(value, fmt, ...)`
Read a signed 32-bit value from a file composed from `fmt`, with
optional args. This function use `vreadllf()` with an additional
range checking for `INT_MIN` and `INT_MAX`. Values outside that
cause this function to return -1 with `errno` set to `ERANGE`.
- `writedf(value, mode, fmt, ...)`
Write a signed 32-bit `value` to a file composed from `fmt`, with
optional args. The file is opened with the given `mode`, e.g. "w+",
which allows for both replacing and appending file content.
The function returns POSIX OK(0) on success or -1 on failure with the
`errno` variable set to a value from either `fopen()` or `fclose()`.
- `writellf(value, mode, fmt, ...)`
Write a signed 64-bit `value` to a file composed from `fmt`, with
optional args. The file is opened with the given `mode`, e.g. "w+",
which allows for both replacing and appending file content.
The function returns POSIX OK(0) on success or -1 on failure with the
`errno` variable set to a value from either `fopen()` or `fclose()`.
GNU Functions
-------------
+3 -3
View File
@@ -21,7 +21,7 @@
# 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
# help (for MS users), 'CHI' for generating a separate .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.
@@ -321,8 +321,8 @@ DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
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],
# Separate CHI file generation.
DX_ARG_ABLE(chi, [generate doxygen separate compressed HTML help index file],
[DX_CHECK_DEPEND(chm, 1)],
[DX_CLEAR_DEPEND(chm, 1)],
[],
+6 -6
View File
@@ -2,21 +2,21 @@ lib_LTLIBRARIES = libite.la
libite_la_CPPFLAGS = -D_GNU_SOURCE
libite_la_CFLAGS = -W -Wall -Wextra
libite_la_LDFLAGS = $(AM_LDFLAGS) -version-info 8:1:3
libite_la_LDFLAGS = $(AM_LDFLAGS) -version-info 9:0:4
libite_la_SOURCES = chomp.c copyfile.c \
conio.c conio.h dir.c \
erasef.c fopenf.c fremove.c \
fexist.c fisdir.c \
fparseln.c fsendfile.c \
ifconfig.c lfile.c \
makepath.c progress.c \
pidfile.c pidfilefn.c \
reallocarray.c rsync.c strtrim.c \
makepath.c procval.c progress.c \
pidfile.c pidfilefn.c popenf.c \
reallocarray.c rsync.c runbg.c \
strlcpy.c strlcat.c strtonum.c \
strdupa.h strndupa.h strnlen.h \
strmatch.c systemf.c touchf.c \
strmatch.c systemf.c strtrim.c \
telnet.c tempfile.c truncatef.c \
yorn.c which.c \
touchf.c yorn.c which.c \
lite.h strlite.h \
queue.h tree.h
+20 -5
View File
@@ -38,6 +38,7 @@ static int adjust_target(const char *src, char **dst)
{
int isdir = 0;
retry:
if (fisdir(*dst)) {
int slash = 0;
char *tmp, *ptr = strrchr(src, '/');
@@ -58,16 +59,25 @@ static int adjust_target(const char *src, char **dst)
sprintf(tmp, "%s%s%s", *dst, slash ? "" : "/", ptr);
*dst = tmp;
} else {
struct stat st;
if (stat(*dst, &st) && fisslashdir(*dst)) {
makedir(*dst, 0755);
goto retry;
}
}
return isdir;
}
/* Actual copy loop, used by both copyfile() and fcopyfile()
* breaks loop on error and EOF */
/*
* Actual copy loop, used by both copyfile() and fcopyfile() breaks loop
* on error and EOF
*/
static ssize_t do_copy(int in, int out, size_t num, char *buffer, size_t len)
{
ssize_t ret = 0, size = 0;
ssize_t ret = 0, size = -1;
do {
size_t count = num > len ? len : num;
@@ -76,11 +86,16 @@ static ssize_t do_copy(int in, int out, size_t num, char *buffer, size_t len)
if (ret <= 0) {
if (ret == -1 && EINTR == errno)
continue;
if (ret == 0 && size == -1)
size = 0;
break;
}
if (ret > 0)
if (ret > 0) {
if (size == -1)
size = 0;
size += write(out, buffer, ret);
}
num -= count;
} while (num > 0);
@@ -194,7 +209,7 @@ ssize_t copyfile(const char *src, const char *dst, int len, int opt)
}
size = do_copy(in, out, num, buffer, BUFSIZ);
if (!size && errno)
if (size < 0)
saved_errno = errno;
else if (keep_mtim)
set_mtime(in, out);
+38
View File
@@ -29,8 +29,13 @@
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include "lite.h"
/**
* Check if a file exists in the file system.
* @param file File to look for, with full path.
@@ -50,6 +55,39 @@ int fexist(const char *file)
return 1;
}
/**
* Like fexist() but with formatted string support
* @param fmt Formatted string to be composed into the file to look for.
*
* This is a wrapper for the fexist() function in lite.h, lessening the
* burden of having to compose the filename from parts in a seprate
* buffer.
*
* @returns @c TRUE(1) if the @a file exists, otherwise @c FALSE(0).
*/
int fexistf(const char *fmt, ...)
{
va_list ap;
char *file;
int len;
va_start(ap, fmt);
len = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
file = alloca(len + 1);
if (!file) {
errno = ENOMEM;
return -1;
}
va_start(ap, fmt);
vsnprintf(file, len + 1, fmt, ap);
va_end(ap);
return fexist(file);
}
/**
* Local Variables:
* indent-tabs-mode: t
+1 -1
View File
@@ -41,7 +41,7 @@ int fisdir(const char *path)
{
struct stat sb;
if (!stat(path, &sb) && S_ISDIR(sb.st_mode))
if (path && !stat(path, &sb) && S_ISDIR(sb.st_mode))
return 1;
return 0;
+39 -15
View File
@@ -27,10 +27,43 @@
#include <stdarg.h>
#include <stdlib.h>
/**
* Similar to fopenf() except it takes a @a va_list argument
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
* @param ap List of variable arguemnts from va_start().
*
* See fopenf() for details.
*
* @returns a FILE pointer, or @c NULL on error.
*/
FILE *vfopenf(const char *mode, const char *fmt, va_list ap)
{
va_list apc;
char *file;
int len;
va_copy(apc, ap);
len = vsnprintf(NULL, 0, fmt, apc);
va_end(apc);
file = alloca(len + 1);
if (!file) {
errno = ENOMEM;
return NULL;
}
va_copy(apc, ap);
vsnprintf(file, len + 1, fmt, apc);
va_end(apc);
return fopen(file, mode);
}
/**
* 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
* @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.
@@ -42,24 +75,15 @@
FILE *fopenf(const char *mode, const char *fmt, ...)
{
va_list ap;
char *file;
int len;
FILE *fp;
va_start(ap, fmt);
len = vsnprintf(NULL, 0, fmt, ap);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
file = alloca(len + 1);
if (!file) {
errno = ENOMEM;
if (!fp)
return NULL;
}
va_start(ap, fmt);
vsnprintf(file, len + 1, fmt, ap);
va_end(ap);
return fopen(file, mode);
return fp;
}
/**
+34 -13
View File
@@ -1,7 +1,7 @@
/* Collection of frog DNA
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
* Copyright (c) 2008-2023 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,7 +26,7 @@
* Collection of frog DNA
* @file lite.h
* @author Claudio Matsuoka (2008-2010)
* @author Joachim Wiberg (2008-2021)
* @author Joachim Wiberg (2008-2023)
* @copyright MIT License
*
* The latest version of this manual and the libite (-lite) software
@@ -44,6 +44,7 @@ extern "C"
#include <errno.h>
#include <fcntl.h> /* Definition of AT_* constants for utimensat() */
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h> /* uint8_t, uint16_t, uint32_t, INT32_MAX, etc. */
#include <sys/stat.h>
#include <sys/types.h>
@@ -72,21 +73,33 @@ typedef struct sdbuf sdbuf_t; /**< Opqaue context struct for telnet APIs */
char *chomp (char *str);
int erasef (const char *fmt, ...);
int erasef (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
char *fparseln (FILE *, size_t *, size_t *, const char[3], int);
int fexist (const char *file);
int fexistf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));;
int fisdir (const char *path);
FILE *fopenf (const char *mode, const char *fmt, ...);
int fremove (const char *fmt, ...);
FILE *vfopenf (const char *mode, const char *fmt, va_list ap);
FILE *fopenf (const char *mode, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
int fremove (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
FILE *tempfile (void);
ssize_t copyfile (const char *src, const char *dst, int len, int opt);
int movefile (const char *src, const char *dst);
int fcopyfile (FILE *src, FILE *dst);
ssize_t fsendfile (FILE *src, FILE *dst, size_t len);
int truncatef (off_t length, const char *fmt, ...);
int truncatef (off_t length, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
char *vreadsnf (char *line, size_t len, const char *fmt, va_list ap);
char *readsnf (char *line, size_t len, const char *fmt, ...);
int writesf (const char *str, const char *mode, const char *fmt, ...);
int vreadllf (long long *value, const char *fmt, va_list ap);
int readllf (long long *value, const char *fmt, ...);
int readdf (int *value, const char *fmt, ...);
int writellf (long long value, const char *mode, const char *fmt, ...);
int writedf (int value, const char *mode, const char *fmt, ...);
int ifconfig (const char *ifname, const char *addr, const char *mask, int up);
@@ -97,13 +110,15 @@ char *lfgetkey (lfile_t *lf, const char *key);
int lfgetint (lfile_t *lf, const char *key);
int fgetint (const char *file, const char *sep, const char *key);
int fmkpath (mode_t mode, const char *fmt, ...);
int fmkpath (mode_t mode, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
int mkpath (const char *dir, mode_t mode);
int makepath (const char *dir);
int dir (const char *dir, const char *type, int (*filter) (const char *file), char ***list, int strip);
int rsync (char *src, char *dst, int opt, int (*filter) (const char *file));
FILE *popenf (const char *type, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
int pidfile (const char *basename);
int pidfile_signal(const char *pidfile, int signal);
pid_t pidfile_read (const char *pidfile);
@@ -114,16 +129,17 @@ void *reallocarray(void *optr, size_t nmemb, size_t size);
void progress (int percent, int max_width);
void progress_simple(int percent);
int systemf (const char *fmt, ...);
int runbg (char *const cmd[], int delay);
int systemf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
sdbuf_t*telnet_open (int addr, short port);
int telnet_close (sdbuf_t *ctx);
int telnet_expect (sdbuf_t *ctx, char *script[], FILE *output);
int telnet_session (int addr, short port, char *script[], FILE *output);
int touchf (const char *fmt, ...);
int touchf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
int yorn (const char *fmt, ...);
int yorn (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
char *which (const char *cmd);
int whichp (const char *cmd);
@@ -139,10 +155,15 @@ int whichp (const char *cmd);
*/
static inline int touch(const char *path)
{
int fd;
if (utimensat(AT_FDCWD, path, NULL, 0)) {
if (errno == ENOENT)
return mknod((path), S_IFREG|0644, 0);
return -1;
if (errno != ENOENT)
return -1;
fd = creat(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd < 0)
return -1;
close(fd);
}
return 0;
}
+63
View File
@@ -0,0 +1,63 @@
/* Formatted popen()
*
* Copyright (c) 2023 Tobias Waldekranz <tobias@waldekranz.com>
* Copyright (c) 2023 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
/**
* Formatted pipe stream to or from a process
* @param type A popen() type, "r" or "w", can also include "e" for @c O_CLOEXEC.
* @param fmt Formatted string to be composed into a shell command line.
*
* This function is an extension to popen(), lessening the burden of
* first having to compose the filename from parts in a seprate buffer.
*
* @returns Upon successful completion, popenf() returns a FILE pointer.
* Otherwise, @c NULL is returned and @a errno is set to indicate the
* error.
*/
FILE *popenf(const char *type, const char *fmt, ...)
{
va_list ap;
char *cmd;
int len;
va_start(ap, fmt);
len = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
cmd = alloca(len + 1);
if (!cmd) {
errno = ENOMEM;
return NULL;
}
va_start(ap, fmt);
vsnprintf(cmd, len + 1, fmt, ap);
va_end(ap);
return popen(cmd, type);
}
+229
View File
@@ -0,0 +1,229 @@
/* Reading and writing values/strings to/from /proc and /sys style files
*
* Copyright (c) 2023 Tobias Waldekranz <tobias@waldekranz.com>
* Copyright (c) 2023 Joachim Wiberg <troglobit@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file procval.c
* @author Joachim Wiberg
* @date 2023
* @copyright ISC License
*/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "lite.h"
/**
* Similar to readsnf() except it takes a @a va_list argument
* @param line Pointer to line buffer.
* @param len Size of line buffer.
* @param fmt Formatted string to be composed into a pathname.
* @param ap List of variable arguemnts from va_start().
*
* For details, see readsnf().
*
* @returns same as readsnf().
*/
char *vreadsnf(char *line, size_t len, const char *fmt, va_list ap)
{
va_list apc;
FILE *fp;
va_copy(apc, ap);
fp = vfopenf("r", fmt, apc);
va_end(apc);
if (!fp)
return NULL;
if (!fgets(line, len, fp)) {
fclose(fp);
return NULL;
}
fclose(fp);
return chomp(line);
}
/**
* Read first line from a file composed from fmt and optional args.
* @param line Pointer to line buffer.
* @param len Size of line buffer.
* @param fmt Formatted string to be composed into a pathname.
*
* @returns On success, this function returns the @p line read from the
* file, with any trailing '\n' chomp()ed out. On error, @c NULL.
*/
char *readsnf(char *line, size_t len, const char *fmt, ...)
{
va_list ap;
char *ln;
va_start(ap, fmt);
ln = vreadsnf(line, len, fmt, ap);
va_end(ap);
return ln;
}
/**
* Write a string buffer to a file composed from fmt and optional args.
* @param str Pointer to string buffer, may be multiple lines.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int writesf(const char *str, const char *mode, const char *fmt, ...)
{
va_list ap;
FILE *fp;
va_start(ap, fmt);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
if (!fp)
return -1;
fprintf(fp, "%s\n", str);
return fclose(fp);
}
/**
* Same as readllf() except it takes a @a va_list argument.
*/
int vreadllf(long long *value, const char *fmt, va_list ap)
{
char line[0x100];
if (!vreadsnf(line, sizeof(line), fmt, ap))
return -1;
errno = 0;
*value = strtoll(line, NULL, 0);
return errno ? -1 : 0;
}
/**
* Read 64-bit integer value from a file composed from fmt and optional args.
* @param value Pointer to where to store read 64-bit integer value.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int readllf(long long *value, const char *fmt, ...)
{
va_list ap;
int rc;
va_start(ap, fmt);
rc = vreadllf(value, fmt, ap);
va_end(ap);
return rc;
}
/**
* Read integer value from a file composed from fmt and optional args.
* @param value Pointer to where to store read integer value.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int readdf(int *value, const char *fmt, ...)
{
long long tmp;
va_list ap;
int rc;
va_start(ap, fmt);
rc = vreadllf(&tmp, fmt, ap);
va_end(ap);
if (rc)
return rc;
if (tmp < INT_MIN || tmp > INT_MAX) {
errno = ERANGE;
return -1;
}
*value = tmp;
return 0;
}
/**
* Write 64-bit integer value to a file composed from fmt and optional args.
* @param value 64-bit integer value to write.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int writellf(long long value, const char *mode, const char *fmt, ...)
{
va_list ap;
FILE *fp;
va_start(ap, fmt);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
if (!fp)
return -1;
fprintf(fp, "%lld\n", value);
return fclose(fp);
}
/**
* Write integer value to a file composed from fmt and optional args.
* @param value Integer value to write.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int writedf(int value, const char *mode, const char *fmt, ...)
{
va_list ap;
FILE *fp;
va_start(ap, fmt);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
if (!fp)
return -1;
fprintf(fp, "%d\n", value);
return fclose(fp);
}
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+5 -3
View File
@@ -77,7 +77,9 @@ int rsync(char *src, char *dst, int opt, int (*filter)(const char *file))
char **files; /* Array of file names. */
struct stat st;
if (!fisdir(dst))
errno = 0;
if (stat(dst, &st) && fisslashdir(dst))
makedir(dst, 0755);
if (!fisdir(src)) {
@@ -85,9 +87,9 @@ int rsync(char *src, char *dst, int opt, int (*filter)(const char *file))
return 1;
if (copy(src, dst, keep_mtim))
result++;
return 1;
return errno;
return 0;
}
/* Copy dir as well? */
+93
View File
@@ -0,0 +1,93 @@
/* Run a command in the background: fork() + usleep() + execvp()
*
* Copyright (c) 2023 Joachim Wiberg <troglobit@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file runbg.c
* @author Joachim Wiberg
* @date 2023
* @copyright ISC License
*/
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
/**
* Run command in the background
* @param cmd NULL terminated list of command and optional arguments
* @param delay Microseconds after fork() to wait before calling cmd
*
* This function forks to run the given command @p cmd in the background.
* To ensure there are no lingering zombies the function actuall forks
* twice, and also calls setsid(), before it calls usleep() with the @p
* delay argument. The command @p cmd is handed over to execvp().
*
* Since it runs in the background it is not possible to get the return
* code of the command.
*
* @returns on successful (first) fork(), this function returns POSIX
* OK(0), otherwise -1 and @a errno is set to indicate the error.
*/
int runbg(char *const cmd[], int delay)
{
int pid = fork();
int rc;
if (!pid) {
int fd, maxfd;
if (setsid() == -1)
_exit(errno);
/* reparent to init */
pid = fork();
if (pid == -1)
_exit(errno);
if (pid > 0)
_exit(0);
maxfd = sysconf(_SC_OPEN_MAX);
if (maxfd == -1)
maxfd = 8192;
for (fd = 0; fd < maxfd; fd++)
close(fd);
usleep(delay);
_exit(execvp(cmd[0], cmd));
}
if (pid == -1)
return -1;
if (waitpid(pid, &rc, 0) == -1)
return -1;
if (WIFEXITED(rc)) {
errno = WEXITSTATUS(rc);
if (errno)
rc = -1;
else
rc = 0;
} else if (WIFSIGNALED(rc)) {
errno = EINTR;
rc = -1;
} else
rc = -1;
return rc;
}
+1
View File
@@ -15,6 +15,7 @@
/printhdr
/progress
/rsync
/runbg
/str
/strmatch
/systemf
+1
View File
@@ -30,6 +30,7 @@ TESTS += pidfile
TESTS += printhdr
TESTS += progress
TESTS += rsync
TESTS += runbg
TESTS += str
TESTS += strmatch
TESTS += systemf
+124 -48
View File
@@ -2,54 +2,130 @@
#include <errno.h>
#include "check.h"
#define ERR(fmt, args...) { printf(fmt ": %s\n", ##args, strerror(errno)); rc = 1; }
#define ERRX(fmt, args...) { printf(fmt "\n", ##args); rc = 1; }
static char *files[] = {
"/etc/passwd", "/tmp/mypwd", "/tmp/mypwd",
"/etc/passwd", "/tmp/", "/tmp/passwd",
"/etc/passwd", "/tmp", "/tmp/passwd",
NULL
};
static int one_sz(const char *src, const char *dst, int sz)
{
struct stat st;
ssize_t len;
int rc = 0;
len = copyfile(src, dst, sz, 0);
if (!len) {
ERR("failed copying any bytes from %s", src);
} else {
if (stat(dst, &st))
ERR("copied but cannot find destination %s", dst);
if (st.st_size != sz)
ERR("file only %ld bytes, expected %d", st.st_size, sz);
if (len != st.st_size)
ERRX("copied expected data %d, but copyfile() says %ld", sz, len);
}
return rc;
}
static int _sz()
{
const int sz = 32768;
return test(one_sz("/dev/zero", "/tmp/zeroes", sz), "copyfile(/dev/zero, %d)", sz);
}
static int fcopyfile_one(const char *src, const char *dst, const char *expected)
{
FILE *from, *to;
int rc;
from = fopen(src, "r");
to = fopen(dst, "w");
rc = fcopyfile(from, to);
if (from)
fclose(from);
if (to)
fclose(to);
if (rc) {
if (!src || !dst)
rc = 0; /* expected */
else if (fisdir(dst))
rc = 0; /* expected */
} else {
if (fexist(expected)) {
if (systemf("diff -q %s %s", src, expected))
rc = 1;
} else
ERR("cannot find %s", expected);
}
erase(expected);
return rc;
}
static int _fcopyfile()
{
int i, rc = 0;
for (i = 0; files[i]; i += 3) {
char *src = files[i];
char *dst = files[i + 1];
char *res = files[i + 2];
rc += test(fcopyfile_one(src, dst, res), "fcopyfile(%s, %s)", src, dst);
}
return rc;
}
/* only checks success, correct file size verified by _sz() */
static int copyfile_one(const char *src, const char *dst, const char *expected)
{
int rc;
rc = copyfile(src, dst, 0, 0);
if (!rc)
rc = 1;
else if (!fexist(expected))
rc = 1;
else
rc = 0;
erase(expected);
return rc;
}
static int _copyfile()
{
int i, rc = 0;
for (i = 0; files[i]; i += 3) {
char *src = files[i];
char *dst = files[i + 1];
char *res = files[i + 2];
rc += test(copyfile_one(src, dst, res), "copyfile(%s, %s)", src, dst);
}
return rc;
}
int main(void)
{
int i = 0;
char *files[] = {
"/etc/passwd", "/tmp/mypwd", "/tmp/mypwd",
"/etc/passwd", "/tmp/", "/tmp/passwd",
"/etc/passwd", "/tmp", "/tmp/passwd",
NULL
};
FILE *src, *dst;
printf("=>Start testing fcopyfile()\n");
while (files[i]) {
printf("fcopyfile(%s, %s)\t", files[i], files[i + 1]);
src = fopen(files[i], "r");
dst = fopen(files[i + 1], "w");
if (fcopyfile(src, dst)) {
if (!fisdir(files[i + 1]))
err(1, "Failed fcopyfile(%s, %s)", files[i], files[i + 1]);
}
if (src)
fclose(src);
if (dst)
fclose(dst);
if (fexist(files[i + 2]))
printf("OK => %s", files[i + 2]);
printf("\n");
erase(files[i + 2]);
i += 3;
}
printf("\n=>Start testing copyfile()\n");
i = 0;
while (files[i]) {
printf("copyfile(%s, %s)\t", files[i], files[i + 1]);
if (!copyfile(files[i], files[i + 1], 0, 0))
err(1, "Failed copyfile(%s, %s)", files[i], files[i + 1]);
if (fexist(files[i + 2]))
printf("OK => %s", files[i + 2]);
printf("\n");
erase(files[i + 2]);
i += 3;
}
return 0;
return _fcopyfile() ||
_copyfile() ||
_sz();
}
+1 -1
View File
@@ -41,7 +41,7 @@ static int mtime()
char buf[80];
/* Must sleep a while here otherwise we execute too fast => no mtime change :-( */
usleep(10000);
sleep(2);
PRINT("Calling pidfile() again to update mtime ...\n");
if (pidfile(pidfile_arg))
+65 -35
View File
@@ -48,52 +48,82 @@ void setup_test(void)
}
}
static void check_tree(char *heading, char *dir)
int check_dir_to_dir(void)
{
if (verbose) {
if (heading)
puts(heading);
int rc = 0;
rc += rsync(SRC, DST, LITE_FOPT_KEEP_MTIME, NULL);
rc += systemf("diff -rq %s %s", SRC, DST);
systemf("rm -rf %s/*", DST);
return rc;
}
int check_file_to_file(void)
{
int rc = 0;
touch(SRC "foo.txt");
PRINT("SRC ==========================\n");
if (verbose) system("ls -l " SRC);
rc += rsync(SRC "foo.txt", DST "foo.txt", LITE_FOPT_KEEP_MTIME, NULL);
if (!fexist(DST "foo.txt") || fisdir(DST "foo.txt")) {
PRINT("No dst file or it's a directory\n");
rc++;
}
// XXX: Fixme, add code to list tree, nftw() possibly
PRINT("DST ==========================\n");
if (verbose) system("ls -l " DST);
systemf("rm -rf %s %s/*", SRC "foo.txt" , DST);
return rc;
}
int check_file_to_dir(void)
{
int rc = 0;
touch(SRC "foo.txt");
PRINT("SRC ==========================\n");
if (verbose) system("ls -l " SRC);
rc += rsync(SRC "foo.txt", DST, LITE_FOPT_KEEP_MTIME, NULL);
if (!fexist(DST "foo.txt") || fisdir(DST "foo.txt"))
rc++;
PRINT("DST ==========================\n");
if (verbose) system("ls -l " DST);
systemf("rm -rf %s %s/*", SRC "foo.txt" , DST);
return rc;
}
int check_file_to_nodir(void)
{
int rc = 0;
touch(SRC "foo.txt");
PRINT("SRC ==========================\n");
if (verbose) system("ls -l " SRC);
system("rm -rf " DST);
rc += rsync(SRC "foo.txt", DST, LITE_FOPT_KEEP_MTIME, NULL);
if (!fexist(DST "foo.txt") || fisdir(DST "foo.txt"))
rc++;
PRINT("DST ==========================\n");
if (verbose) system("ls -l " DST);
systemf("rm -rf %s %s/*", SRC "foo.txt" , DST);
return rc;
}
int run_test(void)
{
int result = 0;
#if 0
setup_test();
check_tree("Before:", BASE);
result += rsync(SRC, DST, 0, NULL);
check_tree("After:", BASE);
cleanup_test();
#endif
setup_test();
sleep(1);
result += rsync(BASE "src", DST, LITE_FOPT_KEEP_MTIME, NULL);
check_tree("Only partial rsync of src <-- No slash!", BASE);
#if 0
cleanup_test();
setup_test();
result += rsync(BASE "src/sub1", BASE "dst", 0, NULL);
check_tree("Only partial rsync of src/sub1 <-- No slashes!!", BASE);
cleanup_test();
setup_test();
result += rsync(BASE "src/sub1/", DST, 0, NULL);
check_tree("Only partial rsync of src/sub1/", BASE);
cleanup_test();
setup_test();
result += rsync(BASE "src/sub1", DST, 0, NULL);
check_tree("Only partial rsync of src/sub1 <-- No slash!", BASE);
result += rsync("/etc", "/var/tmp", 0, NULL);
check_tree("Real life test:", "/var/tmp");
#endif
result += test(check_dir_to_dir(), "Verifying src/ -> dst/");
result += test(check_file_to_file(), "Verifying src/foo.txt -> dst/foo.txt");
result += test(check_file_to_dir(), "Verifying src/foo.txt -> dst/");
result += test(check_file_to_nodir(),"Verifying src/foo.txt -> dst/ (non-existing target dir)");
return result;
}
+23
View File
@@ -0,0 +1,23 @@
#include "check.h"
#define file "/tmp/runbg.txt"
int main(void)
{
char *cmd[] = {
"sh", "-c", "echo 'hello world' > " file, NULL
};
erase(file);
test(runbg(cmd, 100000), "Calling runbg");
if (test(fexist(file), "Verifying %s does not yet exist", file))
return 1;
test(sleep(1), "Waiting for runbg");
if (test(!fexist(file), "Verifying %s has been created", file))
return 1;
return 0;
}
+1 -1
View File
@@ -23,7 +23,7 @@ static int mtime(char *file)
stat(file, &before);
/* Must sleep a while here otherwise we execute too fast => no mtime change :-( */
usleep(10000);
sleep(2);
PRINT("Calling touch() again to update mtime ...\n");
if (touch(file)) {