NBash

Форк
0
395 строк · 9.5 Кб
1
#!/bin/bash
2
#
3
# Copyright (C) 2013-2015, 2017, 2020, 2023  Etersoft
4
# Copyright (C) 2013-2015, 2017, 2020, 2023  Vitaly Lipatov <lav@etersoft.ru>
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU Affero General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU Affero General Public License for more details.
15
#
16
# You should have received a copy of the GNU Affero General Public License
17
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18
#
19

20
PROGDIR=$(dirname $0)
21
[ "$PROGDIR" = "." ] && PROGDIR=$(pwd)
22

23
# will replaced to /usr/share/erc during install
24
SHAREDIR=$(dirname $0)
25

26
load_helper()
27
{
28
    local CMD="$SHAREDIR/$1"
29
    [ -r "$CMD" ] || fatal "Have no $CMD helper file"
30
    . $CMD
31
}
32

33
load_helper erc-sh-functions
34
load_helper erc-sh-archive
35

36
check_tty
37

38
# 1.zip tar:  -> 1.tar
39
build_target_name()
40
{
41
	is_target_format $2 && echo $(get_archive_name "$1").${2/:/} && return
42
	echo "$1"
43
        return 1
44
}
45

46

47
# TODO: list of $HAVE_7Z supported (see list_formats)
48

49
# target file1 [file2...]
50
create_archive()
51
{
52
	local arc="$1"
53
	shift
54
	if have_patool ; then
55
		docmd patool $verbose create "$arc" "$@"
56
		return
57
	fi
58

59
	# FIXME: get type by ext only
60
	local type="$(get_archive_type "$arc")"
61
	case "$type" in
62
		tar)
63
			#docmd $HAVE_7Z a -l $arc "$@"
64
			docmd tar cvf "$arc" "$@"
65
			;;
66
		*)
67
			# TODO: fix symlinks support
68
			docmd $HAVE_7Z a -l "$arc" "$@"
69
			#fatal "Not yet supported creating of $type archives"
70
			;;
71
	esac
72
}
73

74
extract_archive()
75
{
76
	local arc="$1"
77
	shift
78

79
	if have_patool ; then
80
        docmd patool $verbose extract "$arc" "$@"
81
		return
82
	fi
83

84
	local type="$(get_archive_type "$arc")"
85

86
	arc="$(realpath -s "$arc")"
87
	tdir=$(mktemp -d $(pwd)/UXXXXXXXX) && cd "$tdir" || fatal
88

89
	local TSUBDIR="$(basename "$arc" .$type)"
90

91
	case "$type" in
92
		tar.*|tgz)
93
			# TODO: check if there is only one file?
94
			# use subdir if there is no subdir in archive
95
			TSUBDIR="$(basename "$arc" .$(echo $type | sed -e 's|^tar\.||') )"
96
			docmd $HAVE_7Z x -so "$arc" | docmd $HAVE_7Z x -y -si -ttar
97
			;;
98
		*)
99
			docmd $HAVE_7Z x -y "$arc" "$@"
100
			#fatal "Not yet supported extracting of $type archives"
101
			;;
102
	esac
103

104
	cd - >/dev/null
105
	# if only one dir in the subdir
106
	if [ -e "$(echo $tdir/*)" ] ; then
107
		mv $tdir/* .
108
		rmdir $tdir
109
	else
110
		mv $tdir "$TSUBDIR"
111
	fi
112
}
113

114
list_archive()
115
{
116
	local arc="$1"
117
	shift
118

119
	# TODO: move to patool
120
	if [ "$(get_archive_type "$arc" 2>/dev/null)" = "exe" ] ; then
121
		docmd $HAVE_7Z l "$arc" || fatal
122
		return
123
	fi
124

125
	if have_patool ; then
126
		docmd patool $verbose list "$arc" "$@"
127
		return
128
	fi
129

130
	local type="$(get_archive_type "$arc")"
131
	case "$type" in
132
		*)
133
			docmd $HAVE_7Z l "$arc" "$@"
134
			#fatal "Not yet supported listing of $type archives"
135
			;;
136
	esac
137

138
}
139

140
test_archive()
141
{
142
	local arc="$1"
143
	shift
144

145
	# TODO: move to patool
146
	if [ "$(get_archive_type "$arc" 2>/dev/null)" = "exe" ] ; then
147
		docmd $HAVE_7Z t "$arc" || fatal
148
		return
149
	fi
150

151
	if have_patool ; then
152
		docmd patool $verbose test "$arc" "$@"
153
		return
154
	fi
155

156
	local type="$(get_archive_type "$arc")"
157
	case "$type" in
158
		*)
159
			docmd $HAVE_7Z t "$arc" "$@"
160
			#fatal "Not yet supported test of $type archives"
161
			;;
162
	esac
163

164
}
165

166
repack_archive()
167
{
168
	if have_patool ; then
169
		docmd patool $verbose repack "$1" "$2"
170
		return
171
	fi
172

173
	# TODO: if both have tar, try unpack | pack
174

175
	local ftype="$(get_archive_type "$1")"
176
	local ttype="$(get_archive_type "$2")"
177
	case "$ftype-$ttype" in
178
		tar.*-tar|tgz-tar)
179
			docmd $HAVE_7Z x -so "$1" > "$2"
180
			;;
181
		tar-tar.*)
182
			docmd $HAVE_7Z a -si "$2" < "$1"
183
			;;
184
		tar.*-tar.*)
185
			docmd $HAVE_7Z x -so "$1" | $HAVE_7Z a -si "$2"
186
			;;
187
		*)
188
			fatal "Not yet supported repack of $ftype-$ttype archives in 7z mode (try install patool)"
189
			;;
190
	esac
191

192
}
193

194

195
phelp()
196
{
197
	echo "$Descr
198
$Usage
199
 Commands:
200
$(get_help HELPCMD)
201

202
 Options:
203
$(get_help HELPOPT)
204

205
 Examples:
206
    # erc dir - pack dir to dirname.zip
207
    # erc a archive.zip file(s)... - pack files to archive.zip
208
    # erc [x] archive.zip - unpack
209
    # unerc archive.zip - unpack
210
    # erc [repack] archive1.zip... archive2.rar $HAVE_7Z: - repack all to $HAVE_7Z
211
    # erc -f [repack] archive.zip archive.$HAVE_7Z - force repack zip to $HAVE_7Z (override target in anyway)
212
    # erc file/dir zip: - pack file to zip
213
"
214
}
215

216
print_version()
217
{
218
        echo "Etersoft archive manager version @VERSION@"
219
        echo "Copyright (c) Etersoft 2013-2023"
220
        echo "This program may be freely redistributed under the terms of the GNU AGPLv3."
221
}
222

223
progname="${0##*/}"
224

225
Usage="Usage: $progname [options] [<command>] [params]..."
226
Descr="erc - universal archive manager"
227

228
progname="${0##*/}"
229

230

231
force=
232
target=
233
verbose=--verbose
234
use_7z=
235
use_patool=
236

237
if [ -z "$" ] ; then
238
    echo "Etersoft archive manager version @VERSION@" >&2
239
    echo "Run $0 --help to get help" >&2
240
    exit 1
241
fi
242

243
while [ -n "$1" ] ; do
244
case "$1" in
245
    -h|--help|help)       # HELPOPT: this help
246
        phelp
247
        exit
248
        ;;
249
    -V|--version)         # HELPOPT: print version
250
        print_version
251
        exit
252
        ;;
253
    -q|--quiet)           # HELPOPT: be silent
254
        verbose=
255
        ;;
256
    -f|--force)           # HELPOPT: override target
257
        force=-f
258
        ;;
259
    --use-patool)         # HELPOPT: force use patool as backend
260
        use_patool=1
261
        ;;
262
    --use-7z)             # HELPOPT: force use 7z as backend
263
        use_7z=1
264
        ;;
265
    -*)
266
        fatal "Unknown option '$1'"
267
        ;;
268
    *)
269
        break
270
        ;;
271
esac
272
shift
273
done
274

275
set_backend
276

277
cmd="$1"
278

279
eval lastarg=\${$#}
280

281
# Just printout help if run without args
282
if [ -z "$cmd" ] ; then
283
    print_version
284
    echo
285
    fatal "Run $ $progname --help for get help"
286
fi
287

288

289

290
# if the first arg is some archive, suggest extract
291
if get_archive_type "$cmd" 2>/dev/null >/dev/null ; then
292
    if is_target_format $lastarg ; then
293
        cmd=repack
294
    else
295
        cmd=extract
296
    fi
297
# erc dir (pack to zip by default)
298
elif [ -d "$cmd" ] && [ -z "$2" ] ; then
299
    cmd=pack
300
    target=$(basename "$1").zip
301
# erc dir zip:
302
elif test -r "$1" && is_target_format "$2" ; then
303
    cmd=pack
304
elif [ "$progname" = "unerc" ] ; then
305
    cmd=extract
306
else
307
    shift
308
fi
309

310

311
# TODO: Если программа-архиватор не установлена, предлагать установку с помощью epm
312

313
case $cmd in
314
    a|-a|create|pack|add)        # HELPCMD: create archive / add file(s) to archive
315
        # TODO: realize archive addition if already exist (and separate adding?)
316
        if [ -z "$target" ] && is_target_format $lastarg ; then
317
            [ $# = 2 ] || fatal "Need two args"
318
            target="$(build_target_name "$1" "$2")"
319
            # clear last arg
320
            set -- "${@:1:$(($#-1))}"
321
        fi
322
        [ -z "$target" ] && target="$1" && shift
323

324
        [ -e "$target" ] && [ -n "$force" ] && docmd rm -f "$target"
325
        create_archive "$target" "$@"
326
        ;;
327
    e|x|-e|-x|u|-u|extract|unpack)          # HELPCMD: extract files from archive
328
        # TODO: move to patool
329
        if [ "$(get_archive_type "$1" 2>/dev/null)" = "exe" ] ; then
330
            docmd $HAVE_7Z x "$1"
331
            exit
332
        fi
333
        extract_archive "$@"
334
        ;;
335
# TODO: implement deletion
336
#    d|delete)             # HELPCMD: delete file(s) from archive
337
#        docmd patool delete "$@"
338
#        ;;
339
    l|-l|list)               # HELPCMD: list archive contents
340
        list_archive "$@"
341
        ;;
342
    t|-t|test|check)         # HELPCMD: test for archive integrity
343
        test_archive "$@"
344
        ;;
345
    type)                 # HELPCMD: print type of archive
346
        get_archive_type "$1" || fatal "Can't recognize $1 as archive"
347
        ;;
348
    diff)                 # HELPCMD: compare two archive
349
        # check 2 arg
350
        docmd patool $verbose diff "$@"
351
        ;;
352
    b|-b|bench|benchmark)    # HELPCMD: do CPU benchmark
353
        #assure_cmd $HAVE_7Z
354
        # TODO: can be $HAVE_7Za?
355
        docmd $HAVE_7Z b
356
        ;;
357
    search|grep)               # HELPCMD: search in files from archive
358
        docmd patool $verbose search "$@"
359
        ;;
360
    repack|conv)          # HELPCMD: convert source archive to target
361
        # TODO: need repack remove source file?
362
        # TODO: check for 2 arg
363
        if ! is_target_format $lastarg ; then
364
            [ $# = 2 ] || fatal "Need two args"
365
            [ "$(realpath "$1")" = "$(realpath "$2")" ] && warning "Output file is the same as input" && exit
366
            [ -e "$2" ] && [ -n "$force" ] && docmd rm -f "$2"
367
            repack_archive "$1" "$2"
368
            exit
369
        fi
370

371
        # add support for target zip:
372
        for i in "$@" ; do
373
            [ "$i" = "$lastarg" ] && continue
374
            target="$(build_target_name "$i" "$lastarg")"
375
            [ "$(realpath "$1")" = "$(realpath "$target")" ] && warning "Output file is the same as input" && exit
376
            [ -e "$target" ] && [ -n "$force" ] && docmd rm -f "$target"
377
            repack_archive "$i" "$target" || exit
378
        done
379

380
        ;;
381
    formats)              # HELPCMD: lists supported archive formats
382
        # TODO: print allowed with current programs separately
383
        if [ -n "$verbose" ] && have_patool ; then
384
            docmd patool formats "$@"
385
            echo "Also we supports:"
386
            ( list_subformats ; list_extraformats ) | sed -e "s|^|  |"
387
        else
388
            list_formats
389
        fi
390
        ;;
391
    *)
392
        # TODO: If we have archive in parameter, just unpack it
393
        fatal "Unknown command $1"
394
        ;;
395
esac
396

397

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.