3 * This file is part of dds2tar.
4 * Copyright by J"org Weule
6 * Special thanks to Les.Grant@mitsuibabcock.co.uk
11 #include <stdio.h> /* fpirntf() */
12 #include <errno.h> /* perror() */
13 #include <sys/mtio.h> /* MTSEEK ... */
14 #include <sys/ioctl.h> /* ioctl() */
15 #include <unistd.h> /* close() exit() */
24 int dds_scsi2logical(void){
26 p.mt_op = MTSETDRVBUFFER ;
27 p.mt_count = MT_ST_OPTIONS|MT_ST_SCSI2LOGICAL ;
28 fputs("scsi2logical\n",stderr);
29 return ioctl(device,MTIOCTOP,&p);
35 int dds_read_ahead(void){
38 p.mt_op = MTSETDRVBUFFER ;
39 p.mt_count = MT_ST_OPTIONS|MT_ST_READ_AHEAD ;
40 r = ioctl(device,MTIOCTOP,&p);
42 fputs("read_ahead\n",stderr);
43 if ( r < 0 ) perror("Read_ahead");
49 * rewind the last block
55 return ioctl(device,MTIOCTOP,&p);
67 r = ioctl(device,MTSETBLK,&p);
68 if ( r >= 0 ) r = p.mt_count ;
76 int dds_set_bs(int n){
83 fprintf(stderr,"record_size=%d\n",n);
85 return ioctl(device,MTSETBLK,&p);
89 * To read one line of the device and check for errors, we use the following
90 * code. If a filemark is read, we try the block again.
92 * Note that cur_blkno and next_blkno is changed.
95 dds_read_next_block(void)
100 if (next_blkno == -1)
102 next_blkno = dds_getpos(device);
103 cur_blkno = next_blkno;
106 fprintf(stderr, "begin --> read_next_block()\n");
107 fprintf(stderr, "vid=%d \n",vid);
109 if ( vid == HP ) do {
110 /* If you write a tape with 'tar -b 256' on SunOS, reading */
111 /* the tape needs the following workaround. SunOS splits the */
112 /* block into three tape blocks of 65534, 65534 and 4 Bytes. */
113 /* dds2tar is reading the tree blocks and the number is */
114 /* the one of the first block. You can not use the tar */
115 /* listing block is this case, because the calculation of the */
116 /* right will fail. Note that 'dds2tar --dds-dd | tar ft -' */
117 /* will show the index of the archive, 'tar t' fails. */
119 /* --dds-dd is in experimental state, so may be I will change */
121 #if ( ST_BUFFER_BLOCKS > 32 )
123 err = read(device, ((char *) cur_block) + cur_n,
125 if (err > 0) next_blkno++, cur_n += err;
126 } while ((err > 0) && (cur_n < buf_n) && ((cur_n & 0x1ff) != 0));
128 err = read(device, cur_block, buf_n);
129 if (err > 0) next_blkno++, cur_n += err ;
131 if ((cur_n & 0x1ff) != 0) {
132 fprintf(stderr, "not a tar archive, record size is"
133 " %d bytes \n", cur_n);
137 * We are done, if err >= 0.
139 if ( err >= 0 ) break ;
142 * If err < 0 ... exit or decrease the buffer ...
144 if ((errno != EOVERFLOW) || (buf_n == 1)) {
149 fprintf(stderr,"decreasing buffer to %d bytes\n",buf_n);
150 if (buf_n == 1) exit(4);
153 err = read(device, cur_block, tar_n);
156 "Can not read from tape with blocksize of %d.\n",
161 next_blkno += tar_bs , cur_n = err ;
162 if ((cur_n & 0x1ff) != 0) {
163 fprintf(stderr, "not a tar archive, record size is"
164 " %d bytes \n", cur_n);
170 fprintf(stderr, "end ----> read_next_block()\n");
178 dds_read_next_block();
183 dds_getpos(int const dev)
189 i = ioctl(dev, MTIOCPOS, &pos);
191 perror("dds2tar: ioctl MTIOCPOS");
193 i = ioctl(dev, SIOC_GET_POSITION, &n); /* HP-UX */
195 perror("dds2tar: ioctl SIOC_GET_POSITION");
202 fprintf(stderr, "dds2tar: eom detected ? blkno = %d \n", n);
211 dds_getloc(int const dev)
216 i = ioctl(dev, MTIOCPOS, &pos);
218 perror("dds2tar: ioctl MTIOCLOC");
224 fprintf(stderr, "dds2tar: eom detected ? blkno = %d \n", n);
233 dds_has_partitions(int const dev){
237 i = ioctl(dev, MTIOCGET, &p );
240 } else perror("dds2tar");
242 if(i==MT_ISDDS1)fprintf(stderr, "DDS2TAR: drive without partitions\n");
243 if(i==MT_ISDDS2)fprintf(stderr, "DDS2TAR: drive with partitions\n");
244 fprintf(stderr, "DDS2TAR: type = %x\n",i);
253 dds_seek(int const dev, int const blkno)
258 #ifdef SIOC_SET_POSITION
259 i = ioctl(dev, SIOC_SET_POSITION, &blkno);
263 i = ioctl(dev, MTIOCTOP, &op);
266 perror("ioctl SEEK");
274 * This file is part of dds2tar.
275 * Copyright by J"org Weule
279 #include <stdlib.h> /* malloc() */
280 #include <stdio.h> /* printf() */
281 #include <sys/ioctl.h> /* ioctl() */
282 #include <string.h> /* memset() bcopy() */
283 #include <unistd.h> /* exit() */
284 #include "dds_tape.h"
286 typedef unsigned char byte;
297 copy_page(ioctl_arg * const arg, int const i)
301 char const *const text;
309 "set_comp_off", 26, 128,
311 0x15, 0x10, 0x00, 0x00,
312 0x14, 0x00, 0x00, 0x00,
313 0x10, 0x00, 0x0f, 0x0e,
314 0x40, 0x80, 0x00, 0x00,
315 0x00, 0x20, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00
323 "set_cpmp_on", 26, 128,
325 0x15, 0x10, 0x00, 0x00,
326 0x14, 0x00, 0x00, 0x00,
327 0x10, 0x00, 0x0f, 0x0e,
328 0xc0, 0x80, 0x00, 0x00,
329 0x00, 0x20, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00
339 0x1a, 0x00, 0x0f, 0x00, 0x40, 0x00
346 0x4d, 0x00, 0x79, 0x00,
347 0x00, 0x00, 0x00, 0x00,
355 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00
360 "unload_tape", 6, 128,
362 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00
367 "mode_sense", 6, 128,
369 0x1a, 0x00, 0x00, 0x00, 0x0C, 0x00
374 arg->inlen = comp_page[i].inlen;
375 arg->outlen = comp_page[i].outlen;
376 memset(arg->buf, 0, 1024);
377 bcopy(comp_page[i].buf, arg->buf, arg->inlen);
381 print_error(byte const *const b, int len)
384 static char const *const sense_key[] =
386 "no sense", "recovered error", "not ready", "medium error",
387 "hardware error", "illegal request", "unit attention",
388 "data protect", "blank check", "vendor specific",
389 "copy aborted", "aborted command", "equal",
390 "volume overflow", "miscompare", "reserved"
398 for (i = 0; i < len; i++)
399 printf(" %2X", b[i]);
401 printf("error sense: %s\n", sense_key[b[2] & 0xf]);
402 printf("asc + ascq = %2x %2x\n", b[12], b[13]);
407 set_compression_mode(int dev, int const comp_mode)
411 if (comp_mode < 0 || comp_mode > 5)
416 arg = malloc(sizeof (ioctl_arg));
418 fprintf(stderr, "dds2tar: not enough memory\n");
424 copy_page(arg, comp_mode);
425 /* arg->buf[12] = (comp_mode << 7) | 0x40; */
426 if (ioctl(dev, 1, arg) != 0) {
428 print_error(arg->buf, arg->inlen);
431 if (comp_mode == DDSCM_QUERY) {
435 fprintf(stderr, "data compression enable %d\n", b[2] >> 7);
436 } else if (comp_mode == DDSCM_LOG) {
441 for (i = 0; i < b[3];) {
443 static char const *const tab39[] =
450 "kilobytes to data compression",
451 "kilobytes from data compression",
453 "kilobytes from tape",
461 c = (p[0] << 8) + p[1];
466 for (k = 0; k < n; k++)
469 if ((c < 12) && (tab39[c] != NULL))
470 printf("%s: %d\n", tab39[c], j);