summaryrefslogtreecommitdiff
path: root/trunc
blob: 51b62c475246ea13b7fb2323139415ac6da77467 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/bin/sh

#	trunc v.1.0 - Truncate a file to a given length
#
#	Copyright Mikko Rauhala <mjr@iki.fi>, 2009
#
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar at
# http://sam.zoy.org/wtfpl/COPYING and reproduced here:
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004
#
# Copyright (C) 2004 Sam Hocevar
#  14 rue de Plaisance, 75014 Paris, France
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
#  0. You just DO WHAT THE FUCK YOU WANT TO.

#        README:

usage()
{
cat 1>&2 << EOF
Usage:	trunc [-b blocksize] size file(s)
	trunc [--help|-h|--version|-v]

Files will be truncated to the given size. Size is given in bytes
by default, but another block size may also be spesified. If a
file was originally larger than the given size, the rest of it
is lost. If it was smaller, the newly created part of the file
will be filled with zeroes (sparse if supported by the system).
If a file doesn't exist, an empty (sparse) file is created with
the given size and name.

Size is given directly to dd as a count and the optional blocksize
as bs; refer to your system's dd documentation for possible special 
formatting options.

EOF
exit 0
}

# In practice, trunc is a small convenience wrapper for dd, which
# does the entire actual job. The dd recipe isn't all that complicated
# either, but hey, this is still more convenient and some of us find
# ourselves wanting to do this from time to time.

# Technically, we rely on the fact that dd per default (without 
# conv=notrunc) truncates the output file after completing its other
# tasks. We merely tell dd to seek the output file to the given
# position and write nothing.

# There are some idiosyncracies in this script; most of them can be
# explained by me having started scripting first in the mid-90s and
# not bothering to properly find out which of the nicer constructs
# are bashims (which I want to avoid). Yeah, I'm a lazy bastard.

#	History:

# 1.0		Initial release. Slightly cleaned up from rc1 though
#		no actual bugs were found. While cleaning, added also
#		-v and -h.
# 1.0rc1	Initial release candidate. Will be named 1.0 later if
#		no bugs are found.


# Make sure locale settings don't interfere. Might need to rethink and
# isolate this setting to smaller parts of the script if this ever gets 
# localized, but for now, it's okay. (Probably unnecessary in this
# script anyway, I don't _think_ we're doing anything locale-spesific,
# but I've taken this habit to be sure. Doesn't hurt.)
LC_ALL=C
export LC_ALL

ohnoes()
{
	echo "trunc: $1" 1>&2
	exit "$2"
}

if ! which dd > /dev/null; then
	ohnoes "dd not found (why, oh why?)" 3
fi

if [ "a$1" = "a-h" -o "a$1" = "a--help" ]; then
	usage
fi

if [ "a$1" = "a-v" -o "a$1" = "a--version" ]; then
	echo "trunc 1.0 by Mikko Rauhala <mjr@iki.fi>" 1>&2
	exit 0
fi

BS=1
if [ "a$1" = "a-b" ]; then
	if [ "a$2" = "a" ]; then
		usage
	else
		BS="$2"
		shift
		shift
	fi
fi

if [ "a$1" = a -o "a$2" = a ]; then
	usage
fi

SIZE="$1"
shift

for FILE in "$@"; do
	if ! ERROR="`dd if=/dev/null of="$FILE" bs="$BS" count=0 seek="$SIZE" 2>&1`"; then 
		ohnoes "$ERROR" 1
	fi
done

exit 0