mirror of
https://github.com/iustin/mt-st.git
synced 2026-01-11 22:12:49 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8e6d543de | ||
|
|
34978b4019 | ||
|
|
8056c1542a | ||
|
|
c36a4a0fa5 | ||
|
|
f9c0570e34 | ||
|
|
aec3bd67f6 | ||
|
|
52a6c218b9 | ||
|
|
4a72962872 | ||
|
|
c49c863a2a | ||
|
|
b6d221c17a | ||
|
|
e96400b602 | ||
|
|
3c537a17e2 | ||
|
|
bd3b8539d1 | ||
|
|
07e9cd2653 | ||
|
|
1dafc02c2e | ||
|
|
d7e60146d2 | ||
|
|
4fdbc29fed | ||
|
|
fbfd923faa | ||
|
|
886ce1f261 | ||
|
|
1743522b8a | ||
|
|
c33c6ad43e | ||
|
|
51b0d3da23 | ||
|
|
3241491f72 | ||
|
|
5a88467b88 | ||
|
|
9759c9c469 | ||
|
|
5dbcde9d0d | ||
|
|
7366f37f69 |
98
.github/workflows/ci.yml
vendored
Normal file
98
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
on:
|
||||
# Trigger the workflow on push or
|
||||
# pull request, but only for the
|
||||
# main branch.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
# Weekly run to account for
|
||||
# changed dependencies.
|
||||
schedule:
|
||||
- cron: '17 04 * * 0'
|
||||
|
||||
name: CI
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
compiler: ['gcc', 'clang']
|
||||
fail-fast: false
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build the code
|
||||
run: make
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -yy shelltestrunner
|
||||
|
||||
- name: Test creating the release archive
|
||||
run: make distcheck
|
||||
|
||||
coverage:
|
||||
name: Check code coverage
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CC: gcc
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -yy shelltestrunner
|
||||
|
||||
- name: Build the code
|
||||
run: make CFLAGS=-coverage
|
||||
|
||||
- name: Run tests under coverage
|
||||
run: make check
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
name: codecov-gcc
|
||||
#fail_ci_if_error: true
|
||||
verbose: true
|
||||
gcov: true
|
||||
|
||||
sanitizers:
|
||||
name: Test with clang sanitizers
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
compiler: ['clang']
|
||||
# These are the various sanitizers from https://github.com/google/sanitizers:
|
||||
cflags:
|
||||
- '-fsanitize=address -O1 -fno-omit-frame-pointer -g'
|
||||
- '-fsanitize=memory -fsanitize-memory-track-origins -fPIE -pie -fno-omit-frame-pointer -g -O2'
|
||||
- '-fsanitize=undefined'
|
||||
|
||||
fail-fast: false
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
CFLAGS: ${{ matrix.cflags }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build the code
|
||||
run: make
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -yy shelltestrunner
|
||||
|
||||
- name: Run tests
|
||||
run: make check
|
||||
62
.github/workflows/codeql-analysis.yml
vendored
Normal file
62
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '0 5 * * 1'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['cpp']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -8,4 +8,10 @@
|
||||
/mt
|
||||
/stinit
|
||||
/version.h
|
||||
/mt-st-*.tar.gz
|
||||
/mt-st-*.tar.gz*
|
||||
/out/
|
||||
/mt.gcda
|
||||
/mt.gcno
|
||||
/stinit.gcda
|
||||
/stinit.gcno
|
||||
/coverage.info
|
||||
|
||||
15
.travis.yml
15
.travis.yml
@@ -1,15 +0,0 @@
|
||||
#
|
||||
# travis-ci configuration file
|
||||
#
|
||||
language: c
|
||||
# No tests or configuration steps for now
|
||||
script: make && make distcheck
|
||||
# Build with both gcc and clang
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
# Just in case the defaults change, we're only interested in Linux:
|
||||
os:
|
||||
- linux
|
||||
# Use a recent GCC, as otherwise things seem weird
|
||||
dist: bionic
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## Changes in version 1.7 (Thu, 20 Apr 2023)
|
||||
|
||||
Fixes a single bug in stinit parsing of invalid definitions. This is a
|
||||
trivial bug, and only affects config files manually installed by root,
|
||||
so the impact should be minimal.
|
||||
|
||||
The bug also does not appear on amd64/x86, but (in Debian) was only
|
||||
triggered (as undefined behaviour) on mips64el, arm64 and s390x,
|
||||
likely due to different platform behaviour.
|
||||
|
||||
## Changes in version 1.6 (Wed, 19 Apr 2023)
|
||||
|
||||
This is bugfix release agains 1.5. In between 1.4 and 1.5, the "make
|
||||
check" target was migrated to using
|
||||
[shelltest](https://github.com/simonmichael/shelltestrunner), but the
|
||||
`make dist` and `distcheck` targets were no, so the built archive was
|
||||
actually not. This only fixes that and has no functional code changes
|
||||
from 1.5.
|
||||
|
||||
## Changes in version 1.5 (Wed, 19 Apr 2023)
|
||||
|
||||
Trivial release:
|
||||
|
||||
- add IBM 3590 B/E format to tape densities table (Chris Dinneen).
|
||||
|
||||
Thanks!
|
||||
|
||||
## Changes in version 1.4 (Sun, 30 Aug 2020)
|
||||
|
||||
Small bugfixes and improvements release:
|
||||
|
||||
31
Makefile
31
Makefile
@@ -28,7 +28,10 @@ DISTFILES = \
|
||||
.dir-locals.el \
|
||||
.clang-format
|
||||
|
||||
VERSION=1.4
|
||||
TESTFILES = $(wildcard tests/*.test)
|
||||
TESTDATAFILES = $(wildcard tests/data/*.data)
|
||||
|
||||
VERSION=1.7
|
||||
RELEASEDIR=mt-st-$(VERSION)
|
||||
TARFILE=mt-st-$(VERSION).tar.gz
|
||||
|
||||
@@ -58,7 +61,10 @@ dist:
|
||||
trap "rm -rf $$BASE" EXIT && \
|
||||
DIST="$$BASE/$(RELEASEDIR)" && \
|
||||
mkdir "$$DIST" && \
|
||||
$(INSTALL) -m 0644 -p -t "$$DIST/" $(DISTFILES) && \
|
||||
mkdir "$$DIST/tests" && mkdir "$$DIST/tests/data" && \
|
||||
$(INSTALL) -m 0644 -p -t "$$DIST/" $(DISTFILES) && \
|
||||
$(INSTALL) -m 0644 -p -t "$$DIST/tests" $(TESTFILES) && \
|
||||
$(INSTALL) -m 0644 -p -t "$$DIST/tests/data" $(TESTDATAFILES) && \
|
||||
tar czvf $(TARFILE) -C "$$BASE" \
|
||||
--owner root --group root \
|
||||
$(RELEASEDIR)
|
||||
@@ -71,12 +77,7 @@ distcheck: dist
|
||||
tar xvf $(TARFILE) -C "$$SRC" && \
|
||||
cd "$$SRC/$(RELEASEDIR)" && \
|
||||
make CFLAGS="-Wall -Wextra -Werror" && \
|
||||
echo Checking version output && \
|
||||
./mt --version && ./stinit --version && \
|
||||
echo Checking parse status && \
|
||||
./stinit -p -f stinit.def.examples && \
|
||||
echo Checking complete stinit parsing && \
|
||||
( ./stinit -v -v -p -f stinit.def.examples 2>&1 | grep -q 'Mode 1 definition: scsi2logical=1 can-bsr=1 auto-lock=0 two-fms=0 drive-buffering=1 buffer-writes read-ahead=1 async-writes=1 can-partitions=0 fast-eom=1 blocksize=0 sili=1 timeout=900 long-timeout=14400 density=0x44 compression=0' ) && \
|
||||
make check && \
|
||||
make dist && \
|
||||
make install DESTDIR="$$DST" && \
|
||||
numfiles=$$( \
|
||||
@@ -86,11 +87,23 @@ distcheck: dist
|
||||
echo "$$numfiles files installed (5 expected)" && \
|
||||
test "$$numfiles" -eq 5
|
||||
|
||||
check: $(PROGS)
|
||||
shelltest -DVERSION=$(VERSION) tests
|
||||
|
||||
# This needs lcov installed, and it's useful for local testing.
|
||||
coverage: clean
|
||||
$(MAKE) CFLAGS=-coverage
|
||||
$(MAKE) check
|
||||
lcov --capture --directory . --no-external --output-file coverage.info
|
||||
genhtml coverage.info --output-directory out
|
||||
|
||||
|
||||
release-tag:
|
||||
git tag -s -m 'Release version $(VERSION).' mt-st-$(VERSION)
|
||||
|
||||
clean:
|
||||
rm -f *~ \#*\# *.o $(PROGS) version.h
|
||||
rm -f *~ \#*\# *.o *.gcno *.gcda coverage.info $(PROGS) version.h
|
||||
rm -rf out
|
||||
|
||||
reindent:
|
||||
clang-format -i mt.c stinit.c
|
||||
|
||||
@@ -11,8 +11,12 @@ Iustin Pop (<iustin@k1024.org>). For copyright information, see the
|
||||
For more information, bug reports and the source code repository,
|
||||
please see the project homepage at <https://github.com/iustin/mt-st>.
|
||||
|
||||
Build status:
|
||||
[](https://travis-ci.org/iustin/mt-st)
|
||||
[](https://github.com/iustin/mt-st/actions/workflows/ci.yml)
|
||||
[](https://codecov.io/gh/iustin/mt-st)
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## mt
|
||||
|
||||
|
||||
3
mt.c
3
mt.c
@@ -175,7 +175,8 @@ static struct densities {
|
||||
{ 0x26, "DDS-4 or QIC-4GB" },
|
||||
{ 0x27, "Exabyte Mammoth" },
|
||||
{ 0x28, "Exabyte Mammoth-2" },
|
||||
{ 0x29, "QIC-3080MC" },
|
||||
{ 0x29, "QIC-3080MC, IBM 3590 B" },
|
||||
{ 0x2a, "IBM 3590 E" },
|
||||
{ 0x30, "AIT-1 or MLR3" },
|
||||
{ 0x31, "AIT-2" },
|
||||
{ 0x32, "AIT-3 or SLR7" },
|
||||
|
||||
10
stinit.c
10
stinit.c
@@ -139,9 +139,13 @@ static char *find_string(char *s, char *target, char *buf, int buflen)
|
||||
cp++;
|
||||
for (cp2 = cp; *cp2 != '"' && *cp2 != '\0'; cp2++)
|
||||
;
|
||||
} else
|
||||
for (cp2 = cp + 1; isalnum(*cp2) || *cp2 == '-'; cp2++)
|
||||
;
|
||||
} else {
|
||||
if (*cp == '\0')
|
||||
return NULL;
|
||||
else
|
||||
for (cp2 = cp + 1; isalnum(*cp2) || *cp2 == '-'; cp2++)
|
||||
;
|
||||
}
|
||||
if (*cp2 == '\0')
|
||||
return NULL;
|
||||
have_arg = TRUE;
|
||||
|
||||
21
tests/basic.test
Normal file
21
tests/basic.test
Normal file
@@ -0,0 +1,21 @@
|
||||
# Check --version works
|
||||
./mt --version
|
||||
>>> /VERSION/
|
||||
>>>= 0
|
||||
|
||||
./mt -v
|
||||
>>> /VERSION/
|
||||
>>>= 0
|
||||
|
||||
./stinit --version
|
||||
>>> /VERSION/
|
||||
>>>= 0
|
||||
|
||||
# Check -h works
|
||||
./mt -h
|
||||
>>>2 /commands: weof, wset, eof/
|
||||
>>>= 0
|
||||
|
||||
./stinit -h
|
||||
>>>2 /Usage: stinit/
|
||||
>>>= 0
|
||||
6
tests/data/bad-definition.data
Normal file
6
tests/data/bad-definition.data
Normal file
@@ -0,0 +1,6 @@
|
||||
# A non-compressing DAT (DDS-1)
|
||||
# The manufacturer, model, and revision strings can be obtained,
|
||||
# from the file /proc/scsi/scsi (cat /proc/scsi/scsi).
|
||||
manufacturer=XYZ model = "UVW1" {
|
||||
mode1 blocksize=
|
||||
}
|
||||
7
tests/data/illegal-mode.data
Normal file
7
tests/data/illegal-mode.data
Normal file
@@ -0,0 +1,7 @@
|
||||
# A non-compressing DAT (DDS-1)
|
||||
# The manufacturer, model, and revision strings can be obtained,
|
||||
# from the file /proc/scsi/scsi (cat /proc/scsi/scsi).
|
||||
manufacturer=XYZ model = "UVW1" {
|
||||
scsi2logical=1 can-bsr can-partitions auto-lock
|
||||
mode1 blocksize=0
|
||||
modeABC blocksize=1024 }
|
||||
4
tests/data/incomplete-block.data
Normal file
4
tests/data/incomplete-block.data
Normal file
@@ -0,0 +1,4 @@
|
||||
# A non-compressing DAT (DDS-1)
|
||||
# The manufacturer, model, and revision strings can be obtained,
|
||||
# from the file /proc/scsi/scsi (cat /proc/scsi/scsi).
|
||||
manufacturer=XYZ model = "UVW1" {
|
||||
7
tests/data/large-units.data
Normal file
7
tests/data/large-units.data
Normal file
@@ -0,0 +1,7 @@
|
||||
# A non-compressing DAT (DDS-1)
|
||||
# The manufacturer, model, and revision strings can be obtained,
|
||||
# from the file /proc/scsi/scsi (cat /proc/scsi/scsi).
|
||||
manufacturer=XYZ model = "UVW1" {
|
||||
scsi2logical=1 can-bsr can-partitions auto-lock
|
||||
mode1 blocksize=1k
|
||||
mode2 blocksize=1M }
|
||||
34
tests/mt-cli.test
Normal file
34
tests/mt-cli.test
Normal file
@@ -0,0 +1,34 @@
|
||||
# Wrong argument
|
||||
./mt -x
|
||||
>>>2 /usage: /
|
||||
>>>= 1
|
||||
|
||||
# Missing tape argument
|
||||
./mt -f
|
||||
>>>2 /usage: /
|
||||
>>>= 1
|
||||
|
||||
# Unknown command
|
||||
./mt to-the-moon
|
||||
>>>2 /mt: unknown command "to-the-moon"/
|
||||
>>>= 1
|
||||
|
||||
# Too many arguments
|
||||
./mt rewind 1
|
||||
>>>2 /mt: too many arguments for the command 'rewind'\./
|
||||
>>>= 1
|
||||
|
||||
# Ambigous command
|
||||
./mt l
|
||||
>>>2 /mt: ambiguous command "l"/
|
||||
>>>= 1
|
||||
|
||||
# Shortened but not ambiguous command.
|
||||
./mt rewi 1
|
||||
>>>2 /mt: too many arguments for the command 'rewind'\./
|
||||
>>>= 1
|
||||
|
||||
# Densities command - the only one not requiring a tape.
|
||||
./mt densities
|
||||
>>> /LTO-6/
|
||||
>>>= 0
|
||||
4
tests/mt-errors.test
Normal file
4
tests/mt-errors.test
Normal file
@@ -0,0 +1,4 @@
|
||||
# Wrong tape argument
|
||||
./mt -f /dev/no-such-tape rewind
|
||||
>>>2 /no-such-tape: No such file or directory/
|
||||
>>>= 1
|
||||
51
tests/stinit-errors.test
Normal file
51
tests/stinit-errors.test
Normal file
@@ -0,0 +1,51 @@
|
||||
# Check handling of missing file
|
||||
./stinit -p -f no-such-database
|
||||
>>>2 /Can't find SCSI tape database/
|
||||
>>>= 1
|
||||
|
||||
# No file passed
|
||||
./stinit -p -f
|
||||
>>>2 /Usage:/
|
||||
>>>= 1
|
||||
|
||||
# Wrong arguments
|
||||
./stinit -x
|
||||
>>>2 /Usage:/
|
||||
>>>= 1
|
||||
|
||||
# Illegal ordering of arguments
|
||||
./stinit -f stinit.def.examples 1000 -
|
||||
>>>2 /Usage:/
|
||||
>>>= 1
|
||||
|
||||
# Check bad mode
|
||||
./stinit -v -v -p -f tests/data/illegal-mode.data
|
||||
>>> /Errors found!/
|
||||
>>>2 /Illegal mode for/
|
||||
>>>= 1
|
||||
|
||||
# No modes defined
|
||||
#./stinit -v -v -f tests/data/no-modes.data
|
||||
#>>> /Errors found!/
|
||||
#>>>2 /Illegal mode for/
|
||||
#>>>= 1
|
||||
|
||||
# Wrong tape device
|
||||
./stinit -f stinit.def.examples /dev/no-such-tape
|
||||
>>>2 /Can't find tape number for name/
|
||||
>>>= 0
|
||||
|
||||
# Wrong tape number. Well, this is flaky, but let's hope nobody has
|
||||
# 1000 tapes.
|
||||
./stinit -f stinit.def.examples 1000
|
||||
>>>2 /Can't find any device files for tape 1000/
|
||||
>>>= 0
|
||||
|
||||
./stinit -f stinit.def.examples 1000
|
||||
>>>2 /Definition for '1000' failed/
|
||||
>>>= 0
|
||||
|
||||
# Wrong tape number (non-numeric).
|
||||
./stinit -f stinit.def.examples 1000a
|
||||
>>>2 /Invalid tape device index '1000a': don't know how to parse 'a'/
|
||||
>>>= 0
|
||||
30
tests/stinit-parsing.test
Normal file
30
tests/stinit-parsing.test
Normal file
@@ -0,0 +1,30 @@
|
||||
# Check example file parsing
|
||||
./stinit -p -f stinit.def.examples
|
||||
>>>= 0
|
||||
|
||||
# Extra arguments ignored while file parsing
|
||||
./stinit -p -f stinit.def.examples abc
|
||||
>>>2 /Extra arguments .* ignored/
|
||||
>>>= 0
|
||||
|
||||
# Checking complete stinit parsing
|
||||
./stinit -v -v -p -f stinit.def.examples
|
||||
>>> /No errors found./
|
||||
>>>2 /Mode 1 definition: scsi2logical=1 can-bsr=1 auto-lock=0 two-fms=0 drive-buffering=1 buffer-writes read-ahead=1 async-writes=1 can-partitions=0 fast-eom=1 blocksize=0 sili=1 timeout=900 long-timeout=14400 density=0x44 compression=0/
|
||||
>>>= 0
|
||||
|
||||
# Check units
|
||||
./stinit -v -v -p -f tests/data/large-units.data
|
||||
>>> /No errors found./
|
||||
>>>2 /blocksize=1(k|M)/
|
||||
>>>= 0
|
||||
|
||||
# Incomplete block
|
||||
./stinit -p -v -f tests/data/incomplete-block.data
|
||||
>>>2 /End of definition block not found for/
|
||||
>>>= 1
|
||||
|
||||
# Wrong definition
|
||||
./stinit -p -v -f tests/data/bad-definition.data
|
||||
>>>2 /Warning: errors in definition for/
|
||||
>>>= 1
|
||||
Reference in New Issue
Block a user