aboutsummaryrefslogtreecommitdiffstats
path: root/todo/putback.c
blob: 89c54e2a337c2ba60563ccdbcdb11fee3aa2e457 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 * program putback
 *
 * puts back media in scsi-changer
 *
 * usage: /usr/sbin/putback
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

#include <linux/chio.h>

#define PROG     "putback"
#define CHANGER  "/dev/sch0"

#define DEBUG 0  /* set to 1 for debug output */

/* ---------------------------------------------------------------------- */

int main(int argc, char *argv[])
{
    struct changer_params       params;
    struct changer_get_element  *dt;
    struct changer_move         move;
    char                        *h;
    int    fd,i,drive,cside;
    
    if (argc != 1) {
	fprintf(stderr,"Usage: %s\n",argv[0]);
	exit(1);
    }

    if (-1 == (fd = open(CHANGER,O_RDONLY))) {
	perror(PROG ": open " CHANGER);
	exit(1);
    }

    /* read changer status information */
    if (ioctl(fd,CHIOGPARAMS,&params)) {
	perror(PROG ": ioctl CHIOGPARAMS");
	exit(1);
    }
#if DEBUG
    fprintf(stderr,PROG ": %d drives, %d slots\n",
	    params.cp_ndrives,params.cp_nslots);
#endif

    dt = malloc(sizeof(struct changer_get_element)*params.cp_ndrives);
    for (i = 0; i < params.cp_ndrives; i++) {
        dt[i].cge_type=CHET_DT;
	dt[i].cge_unit=i;
	if (ioctl(fd,CHIOGELEM,dt+i)) {
	    fprintf(stderr,PROG ":ioctl CHIOGELEM mt %d: %s\n",
		    i,strerror(errno));
	    exit(1);
	}
	if (NULL != (h = strchr(dt[i].cge_pvoltag,' '))) *h = '\0';
	if (NULL != (h = strchr(dt[i].cge_avoltag,' '))) *h = '\0';
    }


    for (drive=0; drive<params.cp_ndrives; drive++) {

        if (dt[drive].cge_status & CESTATUS_FULL) {
	    /* put back the old media ... */
	    if (!(dt[drive].cge_flags & CGE_SRC)) {
	        fprintf(stderr,PROG ": source element for drive %d unknown\n",
			drive);
		exit(1);
	    }
	    memset(&move,0,sizeof(struct changer_move));
	    move.cm_totype   = dt[drive].cge_srctype;
	    move.cm_tounit   = dt[drive].cge_srcunit;
	    move.cm_fromtype = CHET_DT;
	    move.cm_fromunit = drive;
	    cside = ((dt[drive].cge_flags & CGE_INVERT) == CGE_INVERT);
	    move.cm_flags    = (cside == 0) ? 0 : CM_INVERT;
	    if (ioctl(fd,CHIOMOVE,&move)) {
	        fprintf(stderr,PROG ": ioctl MOVE (unload): %s\n",
			sys_errlist[errno]);
		exit(1);
	    }
	}
    }

    exit(0);
}