##
## plugin to handle tar.gz and tar.bz and tar.Z
##

## global data
set tgz_array(types) "tgz tbz tz"
set tgz_array(tgz_description) "tar, gzip"
set tgz_array(tz_description) "tar, Compress"
set tgz_array(tbz_description) "tar, bzip2"
set tgz_array(tgz_extensions) ".*\.tgz .*\.tar\.gz"
set tgz_array(tz_extensions) ".*\.tar\.Z"
set tgz_array(tbz_extensions) ".*\.tar\.bz .*\.tbz .*\.tbz2 .*\.tar.bz2"

## basic external commands and options
set tgz_array(tarcmd) "tar"
set tgz_array(tgz.cmd) "gzip"
set tgz_array(tbz.cmd) "bzip2"
set tgz_array(tz.cmd) "gzip"
set tgz_array(extract_switch) "--extract"
set tgz_array(compress_switch) "--compress"
set tgz_array(append_switch) "--append"
set tgz_array(list_switch) "-t"
set tgz_array(file_switch) "--file"
set tgz_array(compresscmd_switch) "--use-compress-program"

## options array contains lists - first element is
## a boolean indicating if the option requires arguments
## these are less frequenly used options that aren't
## required for basic operation

## register with the main code
foreach type $tgz_array(types) {register $type}

############ required functions #################

###### return descriptions of the types we have #######
proc tgz.typedesc {} {
    global tgz_array
    return $tgz_array(tgz_description)
}
proc tbz.typedesc {} {
    global tgz_array
    return $tgz_array(tbz_description)
}
proc tz.typedesc {} {
    global tgz_array
    return $tgz_array(tz_description)
}

########## claim incoming filename ###########
## for tgz
proc tgz.matchtype {filename} {
    global tgz_array

    foreach pattern $tgz_array(tgz_extensions) {
	if {[regexp $pattern $filename]} {return 1}
    }
    return 0
}
## for tbz
proc tbz.matchtype {filename} {
    global tgz_array

    foreach pattern $tgz_array(tbz_extensions) {
	if {[regexp $pattern $filename]} {return 1}
    }
    return 0
}
## for tz
proc tz.matchtype {filename} {
    global tgz_array

    foreach pattern $tgz_array(tz_extensions) {
	if {[regexp $pattern $filename]} {return 1}
    }
    return 0
}

######## compress command #########
proc tgz.compresscmd {outfile infiles} {
    ## we're not even here yet
    global status1
    set status1 "compression not yet supported"
}
proc tbz.compresscmd {outfile infiles} {
    tgz.compresscmd
}
proc tz.compresscmd {outfile infiles} {
    tgz.compresscmd
}

######## compress command #########
proc tgz.appendcmd {outfile infiles} {
    ## we're not even here yet
    global status1
    set status1 "appending not yet supported"
}
proc tbz.appendcmd {outfile infiles} {
    tgz.appendcmd
}
proc tz.appendcmd {outfile infiles} {
    tgz.appendcmd
}

####### extract command #######
## main handler for extraction - covers tgz, tz, and tbz
proc tgz.extractcmd {filename destdir files} {
    global status1 tgz_array
    if {[debug]} {puts "tgz.extract called with $filename, $destdir, $files"}

    ## move into the destination directory - that way we
    ## don't have to handle the different outputdir options
    ## or lack thereof with different commands
    cd $destdir

    #### build the commandline ####
    ## assume the type is valid, otherwise we wouldn't
    ## have gotten this far
    set type [matchtype $filename]

    ## add in the compression program switches
    set cmdline "$tgz_array(tarcmd) $tgz_array(compresscmd_switch) \
	    $tgz_array($type.cmd) $tgz_array(extract_switch)"

    ## get the rest of the options in there
    set cmdline [tgz.addoptions $cmdline]
    if {[debug]} {puts "tgz.extractcmd: new cmdline is $cmdline"}
    ## add in the decompress and file switches
    set cmdline "$cmdline $tgz_array(file_switch)"

    if {[llength $files] > 0} {
	catch {eval exec $cmdline $filename $files} tarerror
    } else {
	catch {eval exec $cmdline $filename} tarerror
    }
    if {[string compare $tarerror ""]} {
	doError "Error Extracting $filename:\n $tarerror"
	set status1 "Error Extracting $filename:\n $tarerror"
	return -1
    } else {
	set status1 "Extracted [llength $files] files"
	return 0
    }
}

## stub handlers for bzip2 and unix compress
proc tbz.extractcmd {filename destdir files} {
    tgz.extractcmd $filename $destdir $files
}

proc tz.extractcmd {filename destdir files} {
    tgz.extractcmd $filename $destdir $files
}

####### list files command #######
## for tar,gzip, and everything else
proc tgz.listcmd {filename} {
    global tgz_array status1
    #### build the commandline ####
    ## assume the type is valid, otherwise we wouldn't
    ## have gotten this far
    set type [matchtype $filename]
    
    ## add in the compression program switches
    set cmdline "$tgz_array(tarcmd) $tgz_array(compresscmd_switch) \
	    $tgz_array($type.cmd) $tgz_array(list_switch) \
	    $tgz_array(file_switch)"
    if {[debug]} {puts "tgz.listcmd: cmdline: $cmdline"}
    catch {eval exec $cmdline $filename} listing
    if {![string compare [lindex $listing 0] "$tgz_array(tarcmd):"]} {
	doError "Error listing contents of $filename. \
		Invalid archive?"
	return ""
    }
    return "$listing"
}

## for tar,bzip
proc tbz.listcmd {filename} {
    return [tgz.listcmd $filename]
}

## for tar,compress
proc tz.listcmd {filename} {
    return [tgz.listcmd $filename]
}


######### options setting GUI #############
proc tgz.setoptions {} {
    global status1
    set status1 "setting of options not yet supported"
}
proc tbz.setoptions {} {
    tgz.setoptions
}
proc tz.setoptions {} {
    tgz.setoptions
}

######################## local functions ####################

## add options to commandline
proc tgz.addoptions {cmdline} {
    return $cmdline
}


