#
# Copyright (c) 1992 The Ohio State University.
# All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that: (1) source distributions retain this entire copyright
# notice and comment, and (2) distributions including binaries display
# the following acknowledgement:  ``This product includes software
# developed by The Ohio State University and its contributors''
# in the documentation or other materials provided with the distribution
# and in all advertising materials mentioning features or use of this
# software. Neither the name of the University nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#

#
# Rewind a tape drive.  Run the rewind through the given rsh command
# if there is one.  Returns the status of the command (0 == success, 
# status*256 otherwise.)
#
sub tape_rewind {
    local($rsh, $dev) = @_;
    local($cmd, $result);
    
    $cmd = "$rsh $mt_prog -f $dev rewind";
    print "system: '$cmd'\n";
    print "system: '$cmd'\n" if $opt_d & $DEBUG_SYSTEM;
    $result = system($cmd);

    return($result);
}

#
# Offload the given tape drive, running it through $rsh.  Returns
# status (0 == success, status*256 otherwise).
#
sub tape_offload {
    local($rsh, $dev) = @_;
    local($cmd, $result);
    
    $cmd = "$rsh $mt_prog -f $dev offl";
    print "system: '$cmd'\n" if $opt_d & $DEBUG_SYSTEM;
    $result = system($cmd);

    return($result);
}

#
# FSF the given tape drive, running it through $rsh if given.  Returns 
# status.
#
sub tape_fsf {
    local($rsh, $dev, $number) = @_;
    local($cmd, $result);
    
    $cmd = "$rsh $mt_prog -f $dev fsf $number";
    print "system: '$cmd'\n" if $opt_d & $DEBUG_SYSTEM;
    $result = system($cmd);

    return($result);
}

#
# Determine where we are on the tape.  Sets *file and *block to the 
# file number and block number returned from the mt status command.
# Returns status of the command.
#
sub tape_position {
    local($rsh, $dev, *file, *block) = @_;
    local($cmd, $result);
    
    $cmd = "$rsh $mt_prog -f $dev status|";
    print "open: '$cmd'\n" if $opt_d & $DEBUG_SYSTEM;

    if (! open(STATUS, $cmd)) {
	warn "warning ($0): cannot open '$cmd' ($!)\n";
	return(1);
    }

    $file = -1;
    $block = -1;

line:
    while (<STATUS>) {
	if (/file n.*=\s*(\d*)\s*block n.*=\s*(\d*)/) {
	    $file = $1;
	    $block = $2;
	    last line;
	}
    }

    close(STATUS);

    print "tape_position: at file $file block $block\n" 
      if $opt_d & $DEBUG_INFO;

    if ($file != -1 && $block != -1) {
	return(0);
    } else {
	return(1);
    }
}

#
# Reads the tape ID from the start of a tape.  Returns 0 if it worked,
# 1 otherwise.
#
sub tape_get_id {
    local($rsh, $dev, *id) = @_;
    local($cmd, $label, $magic, $garbage);

    #
    # Read the label off of the tape...
    #
    $cmd = "$rsh $cat_prog $tape_dev | $dd_prog count=1 |";
    print "system: $cmd\n" if $opt_d & $DEBUG_SYSTEM;

    open(LABEL, $cmd) || return(1);

    chop($label = <LABEL>);
    ($magic, $garbage, $id) = split(/[ \t\n]+/, $label);

    close(LABEL);

    #
    # Check the magic number and the tape number...
    #
    if ($magic ne $tape_magic || ! defined($id)) {
        print 
"warning ($0): I cannot get the tape label - maybe the drive is in use, or this is an unlabeled tape.\n";
        return(1);
    }

    return(0);
}

sub tape_put_label {
    local($rsh, $dev, $label) = @_;
    local($cmd);

    if (&tape_rewind($rsh, $dev)) {
	warn "warning ($0): can't rewind the tape to rewrite the label.\n";
	return(1);
    }

    $cmd = "| $rsh $dd_prog of=$dev bs=512 conv=sync";
    print "open: $cmd\n" if $opt_d & $DEBUG_SYSTEM;

    if (! open(DD, $cmd)) {
	warn "warning ($0): dd failed - cannot open dd to rewrite the tape label ($!)\n";
	return(1);
    }
    
    if (! print DD $label) {
	warn "warning ($0): dd failed - cannot write to dd to rewrite the tape label ($!)\n";
	return(1);
    }

    if (! close(DD)) {
	warn "warning ($0): dd failed - cannot close dd to rewrite the tape label ($!)\n";
	return(1);
    }

    print "tape_put_label: tape label is $label\n" if $opt_d & $DEBUG_INFO;
    return(0);
}

1;
