lbu.in 14.3 KB
Newer Older
Natanael Copa's avatar
Natanael Copa committed
1
2
3
4
5
6
#!/bin/sh

# lbu - utility to create local backups.
# Copyright (c) 2006 Natanael Copa
# May be distributed under GPL2

7
VERSION=@VERSION@
Natanael Copa's avatar
Natanael Copa committed
8
sysconfdir=@sysconfdir@
Natanael Copa's avatar
Natanael Copa committed
9

10
11
if [ ! -f ${libalpine:="./libalpine.sh"} ]; then
	libalpine=/usr/share/lbu/libalpine.sh
12
13
14
	if [ ! -f "$libalpine" ]; then
		libalpine=/lib/libalpine.sh
	fi
15
16
fi
. $libalpine || exit 1
Natanael Copa's avatar
Natanael Copa committed
17

Natanael Copa's avatar
Natanael Copa committed
18
19
EXCLUDE_LIST="$sysconfdir"/exclude
INCLUDE_LIST="$sysconfdir"/include
Natanael Copa's avatar
Natanael Copa committed
20

Natanael Copa's avatar
Natanael Copa committed
21
22
DEFAULT_CIPHER="aes-256-cbc"

Natanael Copa's avatar
Natanael Copa committed
23
LBU_CONF="$sysconfdir"/lbu.conf
24
25
26
LBU_PREPACKAGE="$sysconfdir"/pre-package.d
LBU_POSTPACKAGE="$sysconfdir"/post-package.d

Natanael Copa's avatar
Natanael Copa committed
27
28
if [ -f "$LBU_CONF" ]; then
	. "$LBU_CONF"
29
30
fi

Natanael Copa's avatar
Natanael Copa committed
31
32
UMOUNT_LIST=

Natanael Copa's avatar
Natanael Copa committed
33
34
35
36
37
38
39
40
usage() {
	echo "$PROGRAM $VERSION"
	echo "usage: $PROGRAM <subcommand> [options] [args]

Available subcommands:
  commit (ci)
  exclude (ex, delete)
  include (inc, add)
41
42
  list (ls)
  package (pkg)
Natanael Copa's avatar
Natanael Copa committed
43
  status (stat, st)
44
  list-backup (lb) 
Natanael Copa's avatar
Natanael Copa committed
45
  revert
Natanael Copa's avatar
Natanael Copa committed
46
47
48
49
50
51
52
53
54

Common options:
 -h	Show help for subcommand.
 -q	Quiet mode.
 -v	Verbose mode.
"
	exit 1
}

Natanael Copa's avatar
Natanael Copa committed
55
56
57
58
59
60
61
62
63
64
65
66
67
cleanup() {
	local i
	for i in $UMOUNT_LIST; do
		umount $i
	done
}

exit_clean() {
	cleanup
	exit 1
}

mount_once() {
68
	if ! grep $1 /proc/mounts >/dev/null; then
Natanael Copa's avatar
Natanael Copa committed
69
70
71
72
		mount $1 && UMOUNT_LIST="$1 $UMOUNT_LIST"
	fi
}

Natanael Copa's avatar
Natanael Copa committed
73
74
75
# create backupfile
backup_apkovl() {
	local outfile="$1"
76
	local d=$( date -u -r "$outfile" "+%Y%m%d%H%M%S" )
Natanael Copa's avatar
Natanael Copa committed
77
78
79
80
	local backup=$(echo "$outfile" | sed "s/\.apkovl\.tar\.gz/.$d.tar.gz/")
	vecho "Creating backup $backup"
	if [ -z "$DRYRUN" ]; then
		mv "$outfile" "$backup"
Natanael Copa's avatar
Natanael Copa committed
81
		APKOVL_BACKUP="$backup"
Natanael Copa's avatar
Natanael Copa committed
82
83
84
	fi
}

Natanael Copa's avatar
Natanael Copa committed
85
86
87
88
89
90
91
92
restore_apkovl() {
	local outfile="$1"
	if [ -n "$DRYRUN" ] || [ -z "$APKOVL_BACKUP" ]; then
		return 0
	fi
	mv "$APKOVL_BACKUP" "$outfile"
}

Natanael Copa's avatar
Natanael Copa committed
93
# verify we have openssl if we want to encrypt
94
95
96
check_openssl() {
	[ -z "$ENCRYPTION" ] && return 0
	OPENSSL=$(which openssl 2>/dev/null) || die "openssl was not found"
Natanael Copa's avatar
Natanael Copa committed
97

98
99
100
	$OPENSSL list-cipher-commands | grep "^$ENCRYPTION$" > /dev/null \
		|| die "Cipher $ENCRYPTION is not supported"
}
Natanael Copa's avatar
Natanael Copa committed
101
102
103
104
105
106
107
108
109

# list_add(char *listfile, char* file...)
list_add() {
	local list="$1"
	shift
	mkdir -p `dirname "$list"`
	while [ $# -gt 0 ] ; do
		filename=`echo "$1" | sed 's:^/\+::'`
		if grep "^$filename$" "$list" >/dev/null 2>&1 ; then
110
			vecho "$filename is already in $list."
Natanael Copa's avatar
Natanael Copa committed
111
		else
112
			vecho "Adding $filename to $list."
Natanael Copa's avatar
Natanael Copa committed
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
			echo "$filename" >> "$list"
		fi
		shift
	done
}

# list_delete(char *listfile, char *file...)
list_delete() {
	local list="$1"
	local tmp="$list.old"
	shift
	[ -f "$list" ] || return 1
	while [ $# -gt 0 ] ; do
		filename=`echo "$1" | sed 's:^/\+::'`
		mv "$list" "$tmp"
128
		vecho "Removing $filename from list."
Natanael Copa's avatar
Natanael Copa committed
129
130
131
132
133
134
		grep -v "^$filename$" "$tmp" > "$list"
		rm "$tmp"
		shift
	done
}

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# unpack archive on LBU_MEDIA to given dir
unpack_apkovl() {
	local f="$(hostname).apkovl.tar.gz"
	local dest="$1"
	local mnt="/media/$LBU_MEDIA"
	local count=0
	mkdir -p "$dest"
	mount_once "$mnt"
	if [ ! -f "$mnt/$f" ]; then
		return 1
	fi
	if [ -z "$ENCRYPTION" ]; then
		tar -C "$dest" -zxf "$mnt/$f"
		return
	fi
	f="$f.$ENCRYPTION"
	check_openssl
        while [ $count -lt 3 ]; do
		$OPENSSL enc -d -$ENCRYPTION -in "$mnt/$f" | tar \
			-C "$dest" -zx 2>/dev/null && return 0
		count=$(( $count + 1 ))
	done
	cleanup
	die "Failed to unpack $mnt/$f"
}		
160

Natanael Copa's avatar
Natanael Copa committed
161
162
163
164
165
#
# lbu_include - add/remove files to include list
#
usage_include() {
	echo "$PROGRAM $VERSION
Natanael Copa's avatar
Natanael Copa committed
166
Add filename(s) to include list ($sysconfdir/include)
167
168
169

usage: $PROGRAM include|inc|add [-rv] <file> ...
       $PROGRAM include|inc|add [-v] -l
Natanael Copa's avatar
Natanael Copa committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

Options:
  -l	List contents of include list.
  -r	Remove specified file(s) from include list instead of adding.
  -v	Verbose mode.
"
	exit 1
}

cmd_include() {
	if [ "$LIST" ] ; then
		[ $# -gt 0 ] && usage_include
		show_include
		return
	fi
185

Natanael Copa's avatar
Natanael Copa committed
186
187
188
189
190
191
192
193
194
195
196
	[ $# -lt 1 ] && usage_include
	if [ "$REMOVE" ] ; then
		list_delete "$INCLUDE_LIST" "$@"
	else
		list_add "$INCLUDE_LIST" "$@"
		list_delete "$EXCLUDE_LIST" "$@"
	fi
}

show_include() {
	if [ -f "$INCLUDE_LIST" ] ; then
197
		vecho "Include files:"
Natanael Copa's avatar
Natanael Copa committed
198
199
200
201
		cat "$INCLUDE_LIST"
	fi
}

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#
# lbu_package - create a package
#
usage_package() {
	echo "$PROGRAM $VERSION
Create backup package.

usage: $PROGRAM package|pkg -v [<dirname>|<filename>]

Options:
  -v	Verbose mode.

If <dirname> is a directory, a package named <hostname>.apkovl.tar.gz will
be created in the specified directory.

If <filename> is specified, and is not a direcotry, a package with the
specified name willbe created.

220
If <dirname> nor <filename> is not specified, a package named
221
222
223
224
225
226
227
228
229
<hostname>.apkovl.tar.gz will be created in current work directory.
"
	exit 1
}

cmd_package() {
	local pkg="$1"
	local rc=0
	local owd="$PWD"
230
	local suff="apkovl.tar.gz"
Natanael Copa's avatar
Natanael Copa committed
231
	local tmpdir tmppkg
232
233

	check_openssl
Natanael Copa's avatar
Natanael Copa committed
234
	init_tmpdir tmpdir
235

236
237
238
239
	if [ -d "$LBU_PREPACKAGE" ]; then
		run-parts "$LBU_PREPACKAGE" || return 1
	fi

240
	[ -n "$ENCRYPTION" ] && suff="$suff.$ENCRYPTION"
241
242
243

	# find filename
	if [ -d "$pkg" ] ; then
244
		pkg="$pkg/$(hostname).$suff"
245
	elif [ -z "$pkg" ]; then
246
		pkg="$PWD/$(hostname).$suff"
247
248
	fi

Natanael Copa's avatar
Natanael Copa committed
249
250
	tmppkg="$tmpdir/$(basename $pkg)"

251
	cd "${ROOT:-/}"
252
	# remove old package.list
253
	if [ -f etc/lbu/packages.list ] && [ -f var/lib/apk/world ]; then
254
255
256
257
		echo "Note: Removing /etc/lbu/packages.list."
		echo "      /var/lib/apk/world will be used."
		rm -f etc/lbu/packages.list
	fi
258
	currentlist=$(apk audit --backup -q)
259
260
261
	if [ -f var/lib/apk/world ]; then
		currentlist="$currentlist var/lib/apk/world"
	fi
262

263
264
265
	# create tar archive
	[ -f "$EXCLUDE_LIST" ] && excl="-X $EXCLUDE_LIST"
	[ -f "$INCLUDE_LIST" ] && incl="-T $INCLUDE_LIST"
Natanael Copa's avatar
Natanael Copa committed
266
267
268
269
270
	if [ -n "$VERBOSE" ]; then
		echo "Archiving the following files:" >&2
		# we dont want to mess the tar output with the
		# password prompt. Lets get the tar output first.
		tar  $excl $incl -c -v $currentlist > /dev/null
Natanael Copa's avatar
Natanael Copa committed
271
		rc=$?
Natanael Copa's avatar
Natanael Copa committed
272
273
274
275
	fi
	if [ $rc -eq 0 ]; then
		if [ -z "$ENCRYPTION" ]; then
			tar $excl $incl -c $currentlist | gzip -c  >"$tmppkg"
Natanael Copa's avatar
Natanael Copa committed
276
			rc=$?
Natanael Copa's avatar
Natanael Copa committed
277
		else
Natanael Copa's avatar
Natanael Copa committed
278
279
280
281
282
			set -- enc "-$ENCRYPTION" -salt
			[ -n "$PASSWORD" ] && set -- "$@" -pass pass:"$PASSWORD"
			tar $excl $incl -c $currentlist | gzip -c \
				| $OPENSSL "$@" > "$tmppkg"
			rc=$?
283
		fi
284
	fi
Natanael Copa's avatar
Natanael Copa committed
285
	cd "$owd"
Natanael Copa's avatar
Natanael Copa committed
286

Natanael Copa's avatar
Natanael Copa committed
287
	# actually commit unless dryrun mode
Natanael Copa's avatar
Natanael Copa committed
288
	if [ $rc -eq 0 ]; then
289
290
291
292
		if [ -z "$DRYRUN" ]; then
			if [ "x$pkg" = "x-" ]; then
				cat "$tmppkg"
			else
Natanael Copa's avatar
Natanael Copa committed
293
294
295
296
297
298
299
				if cp "$tmppkg" "$pkg.new"; then
					mv "$pkg.new" "$pkg"
					rc=$?
				else
					rm -f "$pkg.new"
					rc=1
				fi
300
301
			fi
		fi
Natanael Copa's avatar
Natanael Copa committed
302
		[ $rc -eq 0 ] && vecho "Created $pkg"
Natanael Copa's avatar
Natanael Copa committed
303
	fi
304
305
306
	if [ -d "$LBU_POSTPACKAGE" ]; then
		run-parts "$LBU_POSTPACKAGE"
	fi
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
	return $rc
}

#
# lbu list - list files that would go to archive
#
usage_list() {
	echo "$PROGRAM $VERSION
Lists files that would go to tar package. Same as: 'lbu package -v /dev/null'

usage: $PROGRAM list|ls
"
	exit 1
}

cmd_list() {
	VERBOSE="-v"
	cmd_package /dev/null
}
Natanael Copa's avatar
Natanael Copa committed
326
327
328
329
330
331

#
# lbu_commit - commit config files to writeable media
#
usage_commit() {
	echo "$PROGRAM $VERSION
332
333
334
Create a backup of config to writeable media.

usage: $PROGRAM commit|ci [-nv] [<media>]
Natanael Copa's avatar
Natanael Copa committed
335
336

Options:
Natanael Copa's avatar
Natanael Copa committed
337
  -d	Remove old apk overlay files.
338
  -e	Protect configuration with a password.
Natanael Copa's avatar
Natanael Copa committed
339
  -n	Don't commit, just show what would have been commited.
Natanael Copa's avatar
Natanael Copa committed
340
  -p <password>	Give encryption password on the command-line
Natanael Copa's avatar
Natanael Copa committed
341
342
343
344
  -v	Verbose mode.

The following values for <media> is supported: floppy usb
If <media> is not specified, the environment variable LBU_MEDIA will be used.
Natanael Copa's avatar
Natanael Copa committed
345

346
Password protection will use $DEFAULT_CIPHER encryption. Other ciphers can be
Natanael Copa's avatar
Natanael Copa committed
347
348
349
used by setting the DEFAULT_CIPHER or ENCRYPTION environment variables.
For possible ciphers, try: openssl -v

Natanael Copa's avatar
Natanael Copa committed
350
351
The password used to encrypt the file, can either be specified with the -p
option or using the PASSWORD environment variable.
352

Natanael Copa's avatar
Natanael Copa committed
353
The environment varialbes can also be set in $LBU_CONF
Natanael Copa's avatar
Natanael Copa committed
354
355
356
357
358
"
	exit 1
}

cmd_commit() {
Natanael Copa's avatar
Natanael Copa committed
359
	local media mnt statuslist tmplist currentlist
360
361
362
363
	local incl excl outfile ovls lines

	check_openssl

Natanael Copa's avatar
Natanael Copa committed
364
365
366
	# turn on verbose mode if dryrun
	[ -n "$DRYRUN" ] && VERBOSE="-v"

367
	# find what media to use
Natanael Copa's avatar
Natanael Copa committed
368
	media="${1:-$LBU_MEDIA}"
Natanael Copa's avatar
Natanael Copa committed
369
370
	[ -z "$media" ] && usage_commit

371
	# mount media unles its already mounted
Natanael Copa's avatar
Natanael Copa committed
372
	mnt=/media/$media
Natanael Copa's avatar
Natanael Copa committed
373
	[ -d "$mnt" ] || usage
Natanael Copa's avatar
Natanael Copa committed
374
	mount_once "$mnt" || die "failed to mount $mnt"
Natanael Copa's avatar
Natanael Copa committed
375

Natanael Copa's avatar
Natanael Copa committed
376
377
378
379
380
381
382
	# find the outfile
	outfile="$mnt/$(hostname).apkovl.tar.gz"
	if [ -n "$ENCRYPTION" ]; then
		outfile="$outfile.$ENCRYPTION"
	fi

	# remove old config files
383
	if [ -n "$DELETEOLDCONFIGS" ] ; then
Natanael Copa's avatar
Natanael Copa committed
384
385
386
387
		local rmfiles=$(ls "$mnt/"*.apkovl.tar.gz* 2>/dev/null)
		if [ -n "$rmfiles" ] ; then
			if [ -n "$VERBOSE" ]; then
				echo "Removing old apk overlay files:" >&2
388
				echo "$rmfiles"
Natanael Copa's avatar
Natanael Copa committed
389
				echo "" >&2
390
			fi
Natanael Copa's avatar
Natanael Copa committed
391
			[ -z "$DRYRUN" ] && rm "$mnt/"*.apkovl.tar.gz*
392
393
		fi
	else
Natanael Copa's avatar
Natanael Copa committed
394
       		lines=$(ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null)
Natanael Copa's avatar
Natanael Copa committed
395
		if [ "$lines" = "$outfile" ]; then
Natanael Copa's avatar
Natanael Copa committed
396
			backup_apkovl "$outfile"
Natanael Copa's avatar
Natanael Copa committed
397
		elif [ -n "$lines" ]; then
398
	               	# More then one apkovl, this is a security concern
Natanael Copa's avatar
Natanael Copa committed
399
			cleanup
Natanael Copa's avatar
Natanael Copa committed
400
401
402
403
			eecho "The following apkovl file(s) were found:"
			eecho "$lines"
			eecho ""
	               	die "Please use -d to replace."
404
		fi
Natanael Copa's avatar
Natanael Copa committed
405
	fi
406
407
408

	# create package
	if ! cmd_package "$outfile"; then
Natanael Copa's avatar
Natanael Copa committed
409
		restore_apkovl "$outfile"
Natanael Copa's avatar
Natanael Copa committed
410
		cleanup
Natanael Copa's avatar
Natanael Copa committed
411
		die "Problems creating archive. aborting"
412
	fi
Natanael Copa's avatar
Natanael Copa committed
413

414
415
	# delete old backups if needed
	# poor mans 'head -n -N' done with awk.
416
	ls "$mnt"/$(hostname).[0-9][0-9][0-9][0-9]*[0-9].tar.gz 2>/dev/null \
417
418
419
420
421
422
423
		| awk '{ a[++i] = $0; } END { 
			print a[0]; 
			while (i-- > '"${BACKUP_LIMIT:-0}"') { 
				print a[++j] 
			}
		}' | xargs rm 2>/dev/null

Natanael Copa's avatar
Natanael Copa committed
424
	# remove obsolete file. some older version of alpine needs this
425
	# to be able to upgrade
426
427
	if [ -z "$DRYRUN" ] && [ -f $mnt/packages.list ]; then
		echo "Note: Removing packages.list from $(basename $mnt)."
428
		echo "      /var/lib/apk/world will be used."
429
430
		rm -f $mnt/packages.list
	fi
Natanael Copa's avatar
Natanael Copa committed
431

Natanael Copa's avatar
Natanael Copa committed
432
	# make sure data is written
Natanael Copa's avatar
Natanael Copa committed
433
	sync
Natanael Copa's avatar
Natanael Copa committed
434
	[ "$media" = "floppy" ] && sleep 1
Natanael Copa's avatar
Natanael Copa committed
435
436

	# move current to commited.
437
	vecho "Successfully saved apk overlay files"
Natanael Copa's avatar
Natanael Copa committed
438
439
440
441
442
443
444
}

#---------------------------------------------------------------------------
# lbu_exclude - add remove file(s) from exclude list

usage_exclude() {
	echo "$PROGRAM $VERSION
Natanael Copa's avatar
Natanael Copa committed
445
Add filename(s) to exclude list ($sysconfdir/exclude)
446
447
448

usage: $PROGRAM exclude|ex|delete [-rv] <file> ...
       $PROGRAM exclude|ex|delete [-v] -l
Natanael Copa's avatar
Natanael Copa committed
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463

Options:
  -l	List contents of exclude list.
  -r	Remove specified file(s) from exclude list instead of adding.
  -v	Verbose mode.
"
	exit 1
}

cmd_exclude() {
	if [ "$LIST" ] ; then
		[ $# -gt 0 ] && usage_exclude
		show_exclude
		return
	fi
464

Natanael Copa's avatar
Natanael Copa committed
465
466
467
468
469
470
471
472
473
474
475
	[ $# -lt 1 ] && usage_exclude
	if [ "$REMOVE" ] ; then
		list_delete "$EXCLUDE_LIST" "$@"
	else
		list_delete "$INCLUDE_LIST" "$@"
		list_add "$EXCLUDE_LIST" "$@"
	fi
}

show_exclude() {
	if [ -f "$EXCLUDE_LIST" ] ; then
476
		vecho "Exclude files:"
Natanael Copa's avatar
Natanael Copa committed
477
		cat "$EXCLUDE_LIST"
478
	fi
Natanael Copa's avatar
Natanael Copa committed
479
480
}

Natanael Copa's avatar
Natanael Copa committed
481
#---------------------------------------------------------------------------
482
# lbu_listbackup - Show old commits
483
usage_listbackup() {
Natanael Copa's avatar
Natanael Copa committed
484
485
486
487
	cat <<EOF
$PROGRAM $VERSION
Show old commits.

488
usage: $PROGRAM list-backup [<media>]
Natanael Copa's avatar
Natanael Copa committed
489
490
491
492
493

EOF
	exit 1
}

494
cmd_listbackup() {
Natanael Copa's avatar
Natanael Copa committed
495
496
	local media=${1:-"$LBU_MEDIA"}
	local mnt="/media/$media"
Natanael Copa's avatar
Natanael Copa committed
497
	[ -z "$media" ] && usage_listbackup
Natanael Copa's avatar
Natanael Copa committed
498
499
500
501
502
503
504
505

	mount_once "$mnt" || die "failed to mount $mnt"
	ls -1 "$mnt"/*.[0-9][0-9]*[0-9][0-9].tar.gz* 2>/dev/null | sed 's:.*/::'
}

#---------------------------------------------------------------------------
# lbu_revert - revert to old config
usage_revert() {
Natanael Copa's avatar
Natanael Copa committed
506
507
508
509
510
511
	cat <<EOF
$PROGRAM $VERSION
Revert to older commit.

usage: $PROGRAM revert <REVISION> [<media>]

Natanael Copa's avatar
Natanael Copa committed
512
The revision should be one of the files listed by 'lbu list-backup'.
Natanael Copa's avatar
Natanael Copa committed
513

Natanael Copa's avatar
Natanael Copa committed
514
EOF
Natanael Copa's avatar
Natanael Copa committed
515
516
517
518
}

cmd_revert() {
	local media=${2:-"$LBU_MEDIA"}
Natanael Copa's avatar
Natanael Copa committed
519
520
521
522
523
524
	[ -z "$media" ] && usage_revert
	local mnt="/media/$media"
	local revertto="$mnt/$1"
	local current="$mnt/$(hostname).apkovl.tar.gz"

	if [ -n "$ENCRYPTION" ]; then
525
		current="$current.$ENCRYPTION"
Natanael Copa's avatar
Natanael Copa committed
526
527
528
	fi
	mount_once "$mnt" || die "failed to mount $mnt"
	[ -f "$revertto" ] || die "file not found: $revertto"
529
	backup_apkovl "$current"
Natanael Copa's avatar
Natanael Copa committed
530
	vecho "Reverting to $1"
531
	[ -z "$DRYRUN" ] && mv "$revertto" "$current"
Natanael Copa's avatar
Natanael Copa committed
532
533
}

Natanael Copa's avatar
Natanael Copa committed
534
535
536
537
538
539
#---------------------------------------------------------------------------
# lbu_status - check what files have been changed since last save
usage_status() {
	echo "$PROGRAM $VERSION
Check what files have been changed since last commit.

540
usage: $PROGRAM status|st [-av]
Natanael Copa's avatar
Natanael Copa committed
541
542
543
544
545
546
547
548

Options:
  -a	Compare all files, not just since last commit.
  -v	Also show include and exclude lists.
"
	exit 1
}

549
550
551
552
553
cmd_status() {
	if [ -n "$USE_DEFAULT" ]; then
		apk audit --backup
		return 0
	fi
554
555
556
557
558
559
560
561
562
	LBU_MEDIA=${1:-"$LBU_MEDIA"}
	[ -z "$LBU_MEDIA" ] && usage_status
	local tmp
	init_tmpdir tmp
	mkdir -p "$tmpdir/a" "$tmp/b"

	# unpack last commited apkovl to tmpdir/a
	unpack_apkovl "$tmp/a"

563
	# generate new apkovl and extract to tmpdir/b
564
565
	cmd_package - | tar -C "$tmp/b" -zx

566
	# show files that exists in a but not in b as deleted
567
568
569
570
571
572
573
	local f
	( cd "$tmp"/a && find ) | while read f; do
		f=${f#./}
		[ "$f" = "." ] && continue
		[ -e "$tmp/b/$f" ] || echo "D $f"
	done
	
574
	# compare files in b with files in a
575
576
577
578
579
580
581
	( cd "$tmp"/b && find ) | while read f; do
		f=${f#./}
		[ "$f" = "." ] && continue
		local a="$tmp/a/$f"
		local b="$tmp/b/$f"
		if [ ! -e "$a" ]; then
			echo "A $f"
Natanael Copa's avatar
Natanael Copa committed
582
583
		elif [ -f "$a" ] && [ -f "$b" ] && [ "$b" -nt "$a" ] \
		     && ! cmp -s "$a" "$b"; then
584
585
586
			echo "U $f"
		fi
	done
587
588
}

Natanael Copa's avatar
Natanael Copa committed
589

590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
#-----------------------------------------------------------
# lbu_diff - run a diff against last commit
usage_diff() {
	echo "$PROGRAM $VERSION
Run a diff against last commit

usage: $PROGRAM diff [<media>]
"
	exit 1
}

cmd_diff() {
	LBU_MEDIA=${1:-"$LBU_MEDIA"}
	[ -z "$LBU_MEDIA" ] && usage_diff
	local tmp
	init_tmpdir tmp
	mkdir -p "$tmpdir/a" "$tmp/b"
	unpack_apkovl "$tmp/a"
	cmd_package - | tar -C "$tmp/b" -zx
	cd "$tmp" && diff -ruN a b 
}
	

Natanael Copa's avatar
Natanael Copa committed
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

#-----------------------------------------------------------
# Main

cmd=`echo "$PROGRAM" | cut -s -d_ -f2`
PROGRAM=`echo "$PROGRAM" | cut -d_ -f1`
if [ -z "$cmd" ] ; then
	cmd="$1"
	[ -z "$cmd" ] && usage
	shift
fi

# check for valid sub command
case "$cmd" in
	include|inc|add)	SUBCMD="include";;
	commit|ci)		SUBCMD="commit";;
	exclude|ex|delete)	SUBCMD="exclude";;
630
631
	list|ls)		SUBCMD="list";;
	package|pkg)		SUBCMD="package";;
Natanael Copa's avatar
Natanael Copa committed
632
	status|stat|st)		SUBCMD="status";;
633
	list-backup|lb)		SUBCMD="listbackup";;
Natanael Copa's avatar
Natanael Copa committed
634
	revert)			SUBCMD="revert";;
635
	diff)			SUBCMD="diff";;
Natanael Copa's avatar
Natanael Copa committed
636
637
638
639
	*)			usage;;
esac

# parse common args
640
while getopts "adehlM:np:qrv" opt ; do
Natanael Copa's avatar
Natanael Copa committed
641
642
643
644
	case "$opt" in
		a) 	[ $SUBCMD = status ] || usage_$SUBCMD
			USE_DEFAULT="-a"
			;;
645
646
		d)	DELETEOLDCONFIGS="yes"
			;;
647
		e)	[ -z "$ENCRYPTION" ] && ENCRYPTION="$DEFAULT_CIPHER"
648
			;;
Natanael Copa's avatar
Natanael Copa committed
649
650
651
652
653
654
655
		h) 	usage_$SUBCMD
			;;
		l)	LIST="-l"
			;;
		n) 	[ $SUBCMD = commit ] || usage_$SUBCMD
			DRYRUN="-n"
			;;
656
657
		p)	PASSWORD="$OPTARG"
			;;
Natanael Copa's avatar
Natanael Copa committed
658
659
660
661
662
663
664
665
666
		q)	QUIET="$QUIET -q"
			;;
		r)	REMOVE="-r"
			;;
		v) 	VERBOSE="$VERBOSE -v"
			;;
	esac
done
shift `expr $OPTIND - 1`
667

Natanael Copa's avatar
Natanael Copa committed
668
trap exit_clean SIGINT SIGTERM
669
cmd_$SUBCMD "$@"
Natanael Copa's avatar
Natanael Copa committed
670
671
672
retcode=$?

cleanup
Natanael Copa's avatar
Natanael Copa committed
673
exit $retcode