wok-6.x view xarchive/stuff/slitaz-wrap.sh @ rev 942

xarchive: add iso, sqfs, cromfs support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Jun 24 15:43:13 2008 +0000 (2008-06-24)
parents cee7a7cd19eb
children 52f4a751924a
line source
1 #!/bin/sh
2 # slitaz-wrap.sh - sh slitaz core wrapper for xarchive frontend
3 # Copyright (C) 2005 Lee Bigelow <ligelowbee@yahoo.com>
4 # Copyright (C) 2008 Pascal Bellard <pascal.bellard@slitaz.org>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 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 General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # set up exit status variables
21 E_UNSUPPORTED=65
23 # Supported file extentions for tar
24 TAR_EXTS="tar"
25 GZIP_EXTS="tar.gz tgz"
26 LZMA_EXTS="tar.lz tar.lzma tlz"
27 BZIP2_EXTS="tar.bz tbz tar.bz2 tbz2"
28 COMPRESS_EXTS="tar.z tar.Z"
29 CPIO_EXTS="cpio"
30 CPIOGZ_EXTS="cpio.gz"
31 ZIP_EXTS="zip cbz jar"
32 RPM_EXTS="rpm"
33 DEB_EXTS="deb"
34 TAZPKG_EXTS="tazpkg"
35 ISO_EXTS="iso"
36 SQUASHFS_EXTS="sqfs squashfs"
37 CROMFS_EXTS="cromfs"
39 # Setup awk program
40 AWK_PROGS="mawk gawk awk"
41 AWK_PROG=""
42 for awkprog in $AWK_PROGS; do
43 if [ "$(which $awkprog)" ]; then
44 AWK_PROG="$awkprog"
45 break
46 fi
47 done
49 # setup variables opt and archive.
50 # the shifting will leave the files passed as
51 # all the remaining args "$@"
52 opt="$1"
53 test -z $1 || shift 1
54 archive="$1"
55 test -z $1 || shift 1
57 # set up compression variables for our compression functions.
58 # translate archive name to lower case for pattern matching.
59 # use compressor -c option to output to stdout and direct it where we want
60 lc_archive="$(echo $archive|tr [:upper:] [:lower:])"
61 DECOMPRESS="cat"
62 COMPRESS="cat"
63 for ext in $GZIP_EXTS $CPIOGZ_EXTS; do
64 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
65 DECOMPRESS="gzip -dc"
66 COMPRESS="gzip -c"
67 fi
68 done
69 for ext in $BZIP2_EXTS; do
70 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
71 DECOMPRESS="bzip2 -dc"
72 COMPRESS="bzip2 -c"
73 fi
74 done
75 for ext in $LZMA_EXTS; do
76 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
77 DECOMPRESS="unlzma -c"
78 COMPRESS="lzma e -si -so"
79 fi
80 done
81 for ext in $COMPRESS_EXTS; do
82 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
83 DECOMPRESS="uncompress -dc"
84 COMPRESS="compress -c"
85 fi
86 done
88 # Compression functions
89 decompress_func()
90 {
91 if [ "$DECOMPRESS" ]; then
92 tmpname="$(mktemp -t tartmp.XXXXXX)"
93 if [ -f "$archive" ]; then
94 $DECOMPRESS "$archive" > "$tmpname"
95 fi
96 # store old name for when we recompress
97 oldarch="$archive"
98 # change working file to decompressed tmp
99 archive="$tmpname"
100 fi
101 }
103 compress_func()
104 {
105 if [ "$COMPRESS" ] && [ "$oldarch" ]; then
106 [ -f "$oldarch" ] && rm "$oldarch"
107 if $COMPRESS < "$archive" > "$oldarch"; then
108 rm "$archive"
109 fi
110 fi
111 }
113 not_busybox()
114 {
115 case "$(readlink $(which $1))" in
116 *busybox*) return 1;;
117 esac
118 return 0
119 }
121 add_file()
122 {
123 ( cd $2 ; tar -cf - $1 ) | tar -xf -
124 }
126 remove_file()
127 {
128 rm -rf ./$1
129 }
131 update_tar_cpio()
132 {
133 action=$1
134 shift
135 tardir="$(dirname "$archive")"
136 for ext in $TAR_EXTS $GZIP_EXTS $BZIP2_EXTS $COMPRESS_EXTS $LZMA_EXTS; do
137 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
138 if [ "$action" = "new_archive" ]; then
139 decompress_func
140 cd "$tardir"
141 tar -cf "$archive" "${1#$tardir/}"
142 status=$?
143 compress_func
144 exit $status
145 fi
146 if not_busybox tar; then
147 decompress_func
148 case "$action" in
149 remove_file)
150 tar --delete -f "$archive" "$@";;
151 add_file)
152 cd "$tardir"
153 tar -rf "$archive" "${1#$tardir/}";;
154 *) false;;
155 esac
156 status=$?
157 compress_func
158 exit $status
159 fi
160 tmptar="$(mktemp -d -t tartmp.XXXXXX)"
161 here="$(pwd)"
162 cd $tmptar
163 $DECOMPRESS < "$archive" | tar -xf -
164 status=$?
165 if [ $status -eq 0 -a -n "$1" ]; then
166 while [ "$1" ]; do
167 $action "${1#$tardir/}" $here
168 shift
169 done
170 tar -cf - $(ls -a | grep -v ^\.$ | grep -v ^\.\.$) | \
171 $COMPRESS > "$archive"
172 status=$?
173 fi
174 cd $here
175 rm -rf $tmptar
176 exit $status
177 fi
178 done
179 for ext in $CPIO_EXTS $CPIOGZ_EXTS; do
180 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
181 if [ "$action" = "new_archive" ]; then
182 decompress_func
183 cd "$tardir"
184 echo "${1#$tardir/}" | cpio -o -H newc > "$archive"
185 status=$?
186 compress_func
187 exit $status
188 fi
189 tmpcpio="$(mktemp -d -t cpiotmp.XXXXXX)"
190 here="$(pwd)"
191 cd $tmpcpio
192 $DECOMPRESS "$archive" | cpio -id > /dev/null
193 status=$?
194 if [ $status -eq 0 -a -n "$1" ]; then
195 while [ "$1" ]; do
196 $action "${1#$tardir/}" $here
197 shift
198 done
199 find . | cpio -o -H newc | $COMPRESS > "$archive"
200 status=$?
201 fi
202 cd $here
203 rm -rf $tmpcpio
204 exit $status
205 fi
206 done
207 }
209 loop_fs()
210 {
211 tmpfs="$(mktemp -d -t fstmp.XXXXXX)"
212 umnt="umount -d"
213 case " $ISO_EXTS " in
214 \ $1\ ) mount -o loop,ro -t iso9660 "$archive" $tmpfs;;
215 esac
216 case " $SQUASHFS_EXTS " in
217 \ $1\ ) mount -o loop,ro -t squashfs "$archive" $tmpfs;;
218 esac
219 case " $CROMFS_EXTS " in
220 \ $1\ ) cromfs-driver "$archive" $tmpfs; umnt="fusermount -u";;
221 esac
222 case "$2" in
223 stat) find $tmpfs | while read f; do
224 [ "$f" = "$tmpfs" ] && continue
225 link="-"
226 [ -L "$f" ] && link=$(readlink "$f")
227 date=$(stat -c "%y" $f | awk \
228 '{ printf "%s;%s\n",$1,substr($2,0,8)}')
229 echo "${f#$tmpfs/};$(stat -c "%s;%A;%U;%G" $f);$date;$link"
230 done;;
231 copy) if [ -z "$3" ]; then
232 ( cd $tmpfs ; tar cf - . ) | tar xf -
233 else
234 while [ -n "$3" ]; do
235 ( cd $tmpfs ; tar cf - "$3" ) | tar xf -
236 shift;
237 done
238 fi;;
239 esac
240 $umnt $tmpfs
241 rmdir $tmpfs
242 }
244 # the option switches
245 case "$opt" in
246 -i) # info: output supported extentions for progs that exist
247 for ext in $TAR_EXTS $GZIP_EXTS $BZIP2_EXTS $COMPRESS_EXTS $LZMA_EXTS \
248 $CPIO_EXTS $CPIOGZ_EXTS $ZIP_EXTS $DEB_EXTS $RPM_EXTS \
249 $TAZPKG_EXTS $ISO_EXTS; do
250 printf "%s;" $ext
251 if [ "$ext" = "zip" -a ! "$(which zip)" ]; then
252 echo warning: zip not found, extract only >/dev/stderr
253 fi
254 done
255 [ -d /lib/modules/$(uname -r)/kernel/fs/squashfs/squashfs.ko ] && \
256 for ext in $SQUASHFS_EXTS; do
257 printf "%s;" $ext
258 done
259 [ -x /bin/cromfs-driver ] && for ext in $CROMFS_EXTS; do
260 printf "%s;" $ext
261 done
262 printf "\n"
263 exit
264 ;;
266 -o) # open: mangle output of tar cmd for xarchive
267 for ext in $TAR_EXTS $GZIP_EXTS $BZIP2_EXTS $COMPRESS_EXTS $LZMA_EXTS; do
268 # format of tar output:
269 # lrwxrwxrwx USR/GRP 0 2005-05-12 00:32:03 file -> /path/to/link
270 # -rw-r--r-- USR/GRP 6622 2005-04-22 12:29:14 file
271 # 1 2 3 4 5 6
272 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
273 $DECOMPRESS "$archive" | tar -tvf - | $AWK_PROG '
274 {
275 attr=$1
276 split($2,ids,"/") #split up the 2nd field to get uid/gid
277 uid=ids[1]
278 gid=ids[2]
279 size=$3
280 date=$4
281 time=$5
283 #this method works with filenames that start with a space (evil!)
284 #split line a time and a space
285 split($0,linesplit, $5 " ")
286 #then split the second item (name&link) at the space arrow space
287 split(linesplit[2], nlsplit, " -> ")
289 name=nlsplit[1]
290 link=nlsplit[2]
292 if (! link) {link="-"} #if there was no link set it to a dash
294 printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
295 }'
296 exit
297 fi
298 done
300 for ext in $CPIO_EXTS $CPIOGZ_EXTS; do
301 # format of cpio output:
302 # lrwxrwxrwx USR/GRP 0 2005-05-12 00:32:03 file -> /path/to/link
303 # -rw-r--r-- USR/GRP 6622 2005-04-22 12:29:14 file
304 # 1 2 3 4 5 6
305 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
306 $DECOMPRESS "$archive" | cpio -tv | $AWK_PROG '
307 {
308 attr=$1
309 split($2,ids,"/") #split up the 2nd field to get uid/gid
310 uid=ids[1]
311 gid=ids[2]
312 size=$3
313 date=$4
314 time=$5
316 #this method works with filenames that start with a space (evil!)
317 #split line a time and a space
318 split($0,linesplit, $5 " ")
319 #then split the second item (name&link) at the space arrow space
320 split(linesplit[2], nlsplit, " -> ")
322 name=nlsplit[1]
323 link=nlsplit[2]
325 if (! link) {link="-"} #if there was no link set it to a dash
327 if (name != "" && uid != "blocks") printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
328 }'
329 exit
330 fi
331 done
333 for ext in $ZIP_EXTS; do
334 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
335 if which zipinfo; then
336 # format of zipinfo -T -s-h- output:
337 # -rw-r--r-- 2.3 unx 11512 tx defN YYYYMMDD.HHMMSS file
338 # 1 2 3 4 5 6 7 8
339 zipinfo -T -s-h-t "$archive" | $AWK_PROG -v uuid=$(id -u -n) '
340 {
341 attr=$1; size=$4
343 year=substr($7,1,4)
344 month=substr($7,5,2)
345 day=substr($7,7,2)
346 date=year "-" month "-" day
348 hours=substr($7,10,2)
349 mins=substr($7,12,2)
350 secs=substr($7,14,2)
351 time=hours ":" mins ":" secs
353 uid=uuid; gid=uuid; link="-"
354 #split line at the time and a space, second item is our name
355 split($0, linesplit, ($7 " "))
356 name=linesplit[2]
357 printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
358 }'
359 exit
360 else
361 # format of unzip -l output:
362 # 6622 2005-04-22 12:29:14 file
363 # 1 2 3 4
364 unzip -l "$archive" | $AWK_PROG -v uuid=$(id -u -n) '
365 BEGIN { n = 0}
366 {
367 n=n+1
368 attr=""
369 uid=uuid; gid=uuid
370 size=$1
371 date=$2
372 time=$3
374 #this method works with filenames that start with a space (evil!)
375 #split line a time and a space
376 split($0,linesplit, $3 " ")
377 #then split the second item (name&link) at the space arrow space
378 split(linesplit[2], nlsplit, " -> ")
380 name=nlsplit[1]
381 link=nlsplit[2]
383 if (! link) {link="-"} #if there was no link set it to a dash
385 if (name != "" && n > 3) printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
386 }'
387 exit
388 fi
389 fi
390 done
392 for ext in $RPM_EXTS; do
393 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
394 rpm2cpio "$archive" | cpio -tv | $AWK_PROG '
395 {
396 attr=$1
397 split($2,ids,"/") #split up the 2nd field to get uid/gid
398 uid=ids[1]
399 gid=ids[2]
400 size=$3
401 date=$4
402 time=$5
404 #this method works with filenames that start with a space (evil!)
405 #split line a time and a space
406 split($0,linesplit, $5 " ")
407 #then split the second item (name&link) at the space arrow space
408 split(linesplit[2], nlsplit, " -> ")
410 name=substr(nlsplit[1],2)
411 link=nlsplit[2]
413 if (! link) {link="-"} #if there was no link set it to a dash
415 if (name != "" && uid != "blocks") printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
416 }'
417 exit
418 fi
419 done
421 for ext in $DEB_EXTS; do
422 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
423 dpkg-deb -c "$archive" | $AWK_PROG '
424 {
425 attr=$1
426 split($2,ids,"/") #split up the 2nd field to get uid/gid
427 uid=ids[1]
428 gid=ids[2]
429 size=$3
430 date=$4
431 time=$5
433 #this method works with filenames that start with a space (evil!)
434 #split line a time and a space
435 split($0,linesplit, $5 " ")
436 #then split the second item (name&link) at the space arrow space
437 split(linesplit[2], nlsplit, " -> ")
439 name=substr(nlsplit[1],2)
440 link=nlsplit[2]
442 if (! link) {link="-"} #if there was no link set it to a dash
444 printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
445 }'
446 exit
447 fi
448 done
450 for ext in $TAZPKG_EXTS; do
451 # format of cpio output:
452 # lrwxrwxrwx USR/GRP 0 2005-05-12 00:32:03 file -> /path/to/link
453 # -rw-r--r-- USR/GRP 6622 2005-04-22 12:29:14 file
454 # 1 2 3 4 5 6
455 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
456 tmpcpio="$(mktemp -d -t cpiotmp.XXXXXX)"
457 here="$(pwd)"
458 cd $tmpcpio
459 cpio -i fs.cpio.gz > /dev/null < "$archive"
460 zcat fs.cpio.gz | cpio -tv | $AWK_PROG '
461 {
462 attr=$1
463 split($2,ids,"/") #split up the 2nd field to get uid/gid
464 uid=ids[1]
465 gid=ids[2]
466 size=$3
467 date=$4
468 time=$5
470 #this method works with filenames that start with a space (evil!)
471 #split line a time and a space
472 split($0,linesplit, $5 " ")
473 #then split the second item (name&link) at the space arrow space
474 split(linesplit[2], nlsplit, " -> ")
476 name=substr(nlsplit[1],3)
477 link=nlsplit[2]
479 if (! link) {link="-"} #if there was no link set it to a dash
481 if (name != "" && uid != "blocks") printf "%s;%s;%s;%s;%s;%s;%s;%s\n",name,size,attr,uid,gid,date,time,link
482 }'
483 cd $here
484 rm -rf $tmpcpio
485 exit
486 fi
487 done
489 for ext in $ISO_EXTS $SQUASHFS_EXTS $CROMFS_EXTS; do
490 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
491 loop_fs $ext stat
492 exit
493 fi
494 done
495 exit $E_UNSUPPORTED
496 ;;
498 -a) # add to archive passed files
499 update_tar_cpio add_file "$@"
500 which zip >/dev/null && for ext in $ZIP_EXTS; do
501 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
502 # we only want to add the file's basename, not
503 # the full path so...
504 while [ "$1" ]; do
505 cd "$(dirname "$1")"
506 zip -g -r "$archive" "$(basename "$1")"
507 wrapper_status=$?
508 shift 1
509 done
510 exit $wrapper_status
511 fi
512 done
513 exit $E_UNSUPPORTED
514 ;;
516 -n) # new: create new archive with passed files
517 update_tar_cpio new_archive "$@"
518 which zip >/dev/null && for ext in $ZIP_EXTS; do
519 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
520 # create will only be passed the first file, the
521 # rest will be "added" to the new archive
522 cd "$(dirname "$1")"
523 zip -r "$archive" "$(basename "$1")"
524 fi
525 done
526 exit $E_UNSUPPORTED
527 ;;
529 -r) # remove: from archive passed files
530 update_tar_cpio remove_file "$@"
531 which zip >/dev/null && for ext in $ZIP_EXTS; do
532 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
533 zip -d "$archive" "$@"
534 fi
535 done
536 exit $E_UNSUPPORTED
537 ;;
539 -e) # extract: from archive passed files
540 for ext in $TAR_EXTS $GZIP_EXTS $BZIP2_EXTS $COMPRESS_EXTS $LZMA_EXTS; do
541 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
542 # xarchive will put is the right extract dir
543 # so we just have to extract.
544 $DECOMPRESS "$archive" | tar -xf - "$@"
545 exit $?
546 fi
547 done
548 for ext in $CPIO_EXTS $CPIOGZ_EXTS; do
549 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
550 if [ -n "$1" ]; then
551 while [ "$1" ]; do
552 $DECOMPRESS "$archive" | cpio -idv "$1"
553 shift 1
554 done
555 else
556 $DECOMPRESS "$archive" | cpio -idv
557 fi
558 exit $?
559 fi
560 done
561 for ext in $ZIP_EXTS; do
562 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
563 # xarchive will put is the right extract dir
564 # so we just have to extract.
565 unzip -n "$archive" "$@"
566 exit $?
567 fi
568 done
569 for ext in $RPM_EXTS; do
570 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
571 if [ -n "$1" ]; then
572 while [ "$1" ]; do
573 rpm2cpio "$archive" | cpio -idv "$1"
574 shift 1
575 done
576 else
577 rpm2cpio "$archive" | cpio -idv
578 fi
579 exit $?
580 fi
581 done
583 for ext in $DEB_EXTS; do
584 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
585 dpkg-deb -X "$archive" "$@"
586 exit $?
587 fi
588 done
589 for ext in $TAZPKG_EXTS; do
590 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
591 tmpcpio="$(mktemp -d -t cpiotmp.XXXXXX)"
592 here="$(pwd)"
593 cd $tmpcpio
594 cpio -i < "$archive" > /dev/null
595 zcat fs.cpio.gz | cpio -id > /dev/null
596 status=$?
597 if [ -n "$1" ]; then
598 while [ "$1" ]; do
599 dir=$(dirname "$here/$1")
600 mkdir -p "$dir" 2> /dev/null
601 mv "fs/$1" "$dir" 2> /dev/null
602 done
603 else
604 mv fs/* fs/.* $here 2> /dev/null
605 fi
606 cd $here
607 rm -rf $tmpcpio
608 exit $status
609 fi
610 done
611 for ext in $ISO_EXTS $SQUASHFS_EXTS $CROMFS_EXTS; do
612 if [ $(expr "$lc_archive" : ".*\."$ext"$") -gt 0 ]; then
613 loop_fs $ext copy "$@"
614 exit 0
615 fi
616 done
617 exit $E_UNSUPPORTED
618 ;;
620 *) echo "error, option $opt not supported"
621 echo "use one of these:"
622 echo "-i #info"
623 echo "-o archive #open"
624 echo "-a archive files #add"
625 echo "-n archive file #new"
626 echo "-r archive files #remove"
627 echo "-e archive files #extract"
628 exit
629 esac