lose the generated ps files
[debian/dds2tar] / dds2tar.c
1 /*
2     dds2tar  Digital-Data-Storage Extract Tool
3
4              This tool makes use of the fast seek command of DAT devices.
5              Files from a selected file archive can be extracted within
6              one minute.
7
8              J"org Weule                     weule@cs.uni-duesseldorf.de
9                                              Fon: +49 211 751409
10
11 ----------------------------------------------------------------------------
12
13                               LICENSE
14
15     This program is free software; you can redistribute it and/or modify
16     it under the terms of the GNU General Public License as published
17     by the Free Software Foundation; either version 1, or (at your option)
18     any later version.
19
20     This program is distributed in the hope that it will be useful,
21     but WITHOUT ANY WARRANTY; without even the implied warranty of
22     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     GNU General Public License for more details.
24
25     You should have received a copy of the GNU General Public License
26     along with this program; if not, write to the Free Software
27     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
29 ----------------------------------------------------------------------------
30
31     To anyone in Germany I declare the following:
32
33     !  Ich werde gegen jede Verbreitung dieser Software rechtlich        !
34     !  vorgehen, welche die Lizenzbestimmungen nicht einh"alt.           !
35
36        Wie f"ur jede andere Software gilt auch hier:
37        Schon mit dem Kopieren oder Benutzen von Teilen dieser Software
38        werden die Lizenzbedingungen stillschweigend akzeptiert. Lesen Sie
39        also die Lizenzbedingungen sorgf"altig! Unkenntnis sch"utzt nicht
40        vor Strafe.
41
42 */
43
44 /*-------------------------------------------------------------------------*/
45
46 #include <stdlib.h>             /* getenv() */
47 #include <stdio.h>
48 #include <string.h>             /* strcmp() strlen() strstr() */
49 #include <sys/types.h>          /* open() stat() */
50 #include <sys/stat.h>           /* stat() */
51 #include <fcntl.h>              /* open() */
52 #include <unistd.h>             /* open() */
53 #include <time.h>               /* ctime() */
54
55 #include "dds2tar.h"
56 #include "dds_tape.h"
57 #include "zf-cre-open.h"
58
59 char vendor[9] = "\0\0\0\0\0\0\0\0\0" ;
60 int vid; /* vendor id */
61
62 /*-------------------------------------------------------------------------*/
63
64 static const char help_text_dds2index[] =
65 "This is dds2index, a tool for fast tape access.\n"
66 "Choose one of the following\n"
67 "-t,--table-of-contents F  get file location from file F\n"
68 "-z,--compress           filter location file through gzip\n"
69 "--z,--no-compress       don't filter location file through gzip\n"
70 "-f,--device F           read the archive from device F\n"
71 "-b,--block-size #       set block size (non HP/SONY)\n"
72 "-B,--Block-size #       set block size (HP or SONY)\n"
73 "-q,--quick              don't extract parent directories from tape\n"
74 "-v,--verbose            verbose mode\n"
75 "--hash-mode             hash mode\n"
76 "--force                 force nochk\n"
77 "--help                  get help\n"
78 "-V,--version            print version number\n"
79 "\n"
80 "Environment:\n"
81 "TAPE                    specifies the tape device\n"
82 "DDS2TAR=[--compress] [-z] [-s #] [-b #]\n"
83 "                        set some defaults\n"
84        ;
85
86 static const char help_text_dds2tar[] =
87 "This is dds2tar, a tool for fast tape access.\n"
88 "Usage: dds2tar [options... ] -t index [pathname ...]  | tar -f - ...\n"
89 "\n"
90 "dds2tar is a tool to read some tar-records from tape and write them\n"
91 "as a tar archive to stdout. You have to use tar to extract the\n"
92 "selected files. The index can either be created by dds2tar or tar.\n"
93 "\n"
94 "Choose one of the following\n"
95 "-t,--table-of-contents F  get file location from file F\n"
96 "-z,--compress           filter location file through gzip\n"
97 "--z,--no-compress       don't filter location file through gzip\n"
98 "-f,--device F           read the archive from device F\n"
99 "-o,--output F           write output to archive file\n"
100 "-b,--block-size #       set block size (non HP/SONY)\n"
101 "-B,--Block-size #       set block size (HP or SONY)\n"
102 "-s,--first_block #      set number of the first block\n"
103 "--body                  print only the contents of the first file an quit\n"
104 "-v,--verbose            verbose mode\n"
105 "--help                  get help\n"
106 "-V,--version            print version number\n"
107 "\n"
108 "Environment:\n"
109 "TAPE                    specifies the tape device\n"
110 "DDS2TAR=[--compress] [-z] [-s #] [-b #]\n"
111 "                        set some defaults\n"
112        ;
113
114 static const char help_text_mt_dds[] =
115 "This is mt-dds, a tool to control the dds-device.\n"
116 "Usage: mt-dds [-f device] <action>\n"
117 "\n"
118 "Choose one or none of the following actions:\n"
119 #ifdef HPDAT
120 "comp-on      set compression mode on\n"
121 "comp-off     set compression mode off\n"
122 "comp-query   query compression mode\n"
123 "comp-log     print compression log page\n"
124 #endif
125 "-b           set the buffer size\n"
126 "blksize      print the block size of the archive with format\n"
127 "tell         print current location and blocksize\n"
128 "where        print current location\n"
129 "label        print the label of the current archive\n"
130 "             if it begins at the current position\n"
131 "filename     print the filename of the current record\n"
132 "             if a header record is found at the current position\n"
133 "ts           print the timestamp of the current archive\n"
134 "date         print the date of the current archive\n"
135 "scsi2logical select mode scsi2logical first\n"
136 "             if it begins at the current position\n"
137 "date <timestamp> convert the stamp to a string\n"
138        ;
139
140 static const char help_text_dds_dd[] =
141 "This is dds-dd, a tool to read the dds-device.\n"
142 "Usage: dds-dd` [-f device] | tar -f - -[x|t] ... \n";
143
144 /*-------------------------------------------------------------------------*/
145
146 static const char version[] =
147 "Version " VERSION " -- last change 1994 Dez 22." ;
148
149 /*-------------------------------------------------------------------------*/
150
151 /* This is the source for dds2tar, dds2index and mt-dds. The program will
152    use the variable pg to decide witch version is running. The default
153    can be set in the Makefile and is overwritten by the value of argv[0].
154    If you give --dds2tar, --dds2index or --mt-dds as an option, the
155    program will run instead of these.
156 */
157
158 #define DDS2TAR name_dds2tar
159 static char const name_dds2tar[] = "dds2tar";
160
161 #define DDS2INDEX name_dds2index
162 static char const name_dds2index[] = "dds2index";
163
164 #define MTDDS name_mtdds
165 static char const name_mtdds[] = "mt-dds";
166
167 #define DDS_DD name_dds_dd
168 static char const name_dds_dd[] = "dds-dd";
169
170
171 #if ( PROGRAM == DDS2TAR )
172 char const *pg = name_dds2tar;
173 char const *help_text = help_text_dds2tar;
174
175 #elif ( PROGRAM == DDS2INDEX )
176 char const *pg = name_dds2index;
177 char const *help_text = help_text_dds2index;
178
179 #elif ( PROGRAM == DDS2TAR )
180 char const *pg = name_mtdds;
181 char const *help_text = help_text_mt_dds;
182
183 #elif ( PROGRAM == DDS_DD )
184 char const *pg = name_dds_dd;
185 char const *help_text = help_text_dds_dd;
186
187 #else
188 char const *pg = name_dds2tar;
189 char   *help_text = help_text_dds2tar;
190
191 #endif
192
193 #define LOCATION 1
194 #define EXTRACT 2
195
196 /*-------------------------------------------------------------------------*/
197
198 char const dds_old_headline[] =
199 "magic record blk:     size name\n";
200
201 char const dds_old_index_format[] =
202 "%6s%7d%3d:%9d %s\n";
203
204 /* magic blkno recno: size name */
205
206 char const dds_old_index_scan_format[] =
207 "%6c%7d%3d:%9d\n";
208
209 char const dds_headline[] =
210 "magic  record blk:     size name\n";
211
212 char const dds_index_format[] =
213 "%6s%7d%4d:%9d %s\n";
214
215 /* magic blkno recno: size name */
216
217 char const dds_index_scan_format[] =
218 "%6c%7d%4d:%9d\n";
219
220 /* magic blkno recno: size name */
221
222 char const dds_loctext[] =
223 "first block number is %d\n"
224 "block size is %d\n" "block length is %d\n";
225
226 char const dds_locline1[] =
227 "loc             number of the first block is %d\n";
228
229 char const dds_locline2[] =
230 "loc             block length is %d bytes = %d * 512 bytes\n";
231
232 /* to handle long link and long file names */
233 int long_name_len = 0 ;
234 char long_name[MAXPATHLEN<<2] = { '\0' };
235
236 int
237 rt_loc_line(void)
238 {
239 #define strneq(a,b,n) strncmp(a,b,n)==0
240
241         if ( strneq(cur_line, dds_locline1, 45) ) {
242                 tar_fb = atoi(cur_line + 45);
243         } else
244         if ( strneq(cur_line, "first block number is", 21) ) {
245                 tar_fb = atoi(cur_line + 21);
246         } else
247         if ( strneq(cur_line, dds_locline2, 31) ) {
248                 tar_n = atoi(cur_line + 31);
249                 tar_bs = tar_n >> 9;
250         } else
251         if ( strneq(cur_line, "block size is", 13) ) {
252                 tar_bs = atoi(cur_line + 13);
253                 tar_n = tar_bs << 9;
254         } else
255         if ( strneq(cur_line, "block length is", 15) ) {
256                 tar_n = atoi(cur_line + 15) ;
257                 tar_bs = tar_n >> 9 ;
258         } else {
259                 return 1;
260         }
261
262         if ( verbose ) fprintf(stderr,
263                 "block length is %d = %d * 512 \n", tar_n, tar_bs );
264
265 #undef strneq
266
267         if ( buf_n < tar_n ) {
268                 cur_block = realloc ( cur_block , buf_n = tar_n );
269                 if ( cur_block == NULL ) {
270                         fprintf(stderr, "%s: No memory available.\n", pg);
271                         exit(2);
272                 }
273         }
274         return 0;
275 }
276
277
278 /*-------------------------------------------------------------------------*/
279
280 int     verbose = 0;
281 int     hash_mode = 0;
282 int     list_only = 0;          /* print only the matched names */
283 int     quick_mode = 0;         /* don't extract parent directories also */
284 int     device;                 /* file number of the device */
285 int     write_body = 0 ;        /* write only the body of the first file */
286 int     get_label = 0 ;         /* get the label of the archive */
287 int     get_filename = 0 ;      /* get the filename of the current record */
288 int     get_blocksize = 0 ;     /* get the blocksize of the current record */
289 int     get_timestamp = 0 ;     /* get the timestamp of the archive */
290 int     get_date = 0 ;          /* get the date of the archive */
291 int     get_fileno = 0 ;        /* get the number of the current */
292 int     force_nochk = 0 ;       /* force tape read, no check of headers */
293
294 /* file io */
295 FILE   *index_fp = NULL;
296
297 /* archive location as set by arguments or index file */
298 int     tar_fb = 0;             /* first block of the archive */
299 int     tar_bs = 20;            /* block size in records of 512 bytes */
300 int     tar_n = 10240;          /* block length in bytes */
301
302 /* archive buffer and location as set by tape access */
303 tar_record *cur_block;
304 int     cur_blkno = -1;
305 int     next_blkno = -1 ;
306 int     cur_bs;
307 int     cur_n;
308 int     buf_n = ST_BUFFER_BLOCKS << 10 ;
309
310 /* line buffer to scan the index file */
311 char   *cur_line;
312
313 /*-------------------------------------------------------------------------*/
314
315 /********
316         *  input: name of the device ( e.g. /dev/nst0, /dev/nrmt0 or NULL )
317         *         open mode of the device ( e.g. O_RDONLY or O_WRONLY )
318         *         verbose flag to indicate the logging mode (integer)
319         * output: channel number ( integer ) for use with 'read()' or 'write()'
320         *
321         * side effects: none
322         *
323         **********************************************************************/
324
325 static int
326 open_device(char const *pathname, int const open_mode)
327 {
328         int     fd;
329         int     i = 1;
330         char   const *p = "next try to open the tape %s\n";
331
332         {
333                 int i ;
334                 struct stat s ;
335                 FILE *f ;
336                 char cmd[100];
337                 i = stat(pathname,&s);
338                 if ( i < 0 ) perror("dds2tar"),exit(1);
339                 sprintf(cmd,"scsi_vendor tape %d",(int)(s.st_rdev&0x7f)+1);
340                 f = popen(cmd,"r");
341                 fread(vendor,1,8,f);
342                 fclose(f);
343                 for ( i = 0 ; i < 8 ; i++ )
344                         ( vendor[i] < 0x20 ) && ( vendor[i] = '\0' ) ;
345                 if ( !strcmp(vendor,"HP") ) vid = HP ;
346                 if ( !strcmp(vendor,"SONY") ) vid = SONY ;
347                 if ( !strcmp(vendor,"ARCHIVE") ) vid = ARCHIVE ;
348                 if ( !strcmp(vendor,"SEGATE") ) vid = SEGATE ;
349                 if ( !strcmp(vendor,"EXABYTE") ) vid = EXABYTE ;
350         }
351                 
352         do {
353                 if ((fd = open(pathname, open_mode)) >= 0)
354                         break;
355                 sleep(2);
356                 if (verbose)
357                         fprintf(stderr, p, pathname);
358         } while ((++i) <= 15);
359         if (fd < 0) {
360                 perror("tape busy?");
361                 exit(1);
362         } /* else dds_has_partitions(fd); */
363         return fd;
364 }
365
366 /*-------------------------------------------------------------------------*/
367 int
368 strprefix(char**s,char*p,char*q){
369         while ( p != 0 ) {
370                 char *t = *s ; while (( *p != 0 ) && ( *p == *t )) p++ , t++ ;
371                 if ( *p == 0 ) { *s = t ; return 1 ; }
372                 p = q ; q = NULL ;
373         } return 0 ;
374 }
375 /*-------------------------------------------------------------------------*/
376
377 /*
378  * dds2tar
379  */
380 int
381 main(int argc, char *const *argv)
382 {
383
384 #ifndef DEVICE
385 #define DEVICE "/dev/rmt0"
386 #endif
387
388         int     density = 0 ;
389         int     n = 1;
390         int     l = strlen(argv[0]);
391         int     compressed_mode = T_MODE;
392         char   *p;
393         int     child_proc = -1;/* child not running */
394         char const *index_file = NULL;
395         int     print_location = 0;
396         int     print_blksize = 0;
397         int     mt_action = DDSCM_NULL; /* turn compression on/off */
398         int     mode = 0;       /* mode of dds2tar */
399         char const *const *pattern_list = NULL;
400         char const *device_name = DEVICE;
401
402         if ((p = getenv("TAPE")) != NULL)
403                 device_name = p;
404
405         if (!strcmp(argv[0] + l - 7, "dds2tar")) {
406                 pg = DDS2TAR;
407                 help_text = help_text_dds2tar;
408         }
409         if (!strcmp(argv[0] + l - 9, "dds2index")) {
410                 pg = DDS2INDEX;
411                 help_text = help_text_dds2index;
412         }
413         if (!strcmp(argv[0] + l - 6, "mt-dds")) {
414                 pg = MTDDS;
415                 help_text = help_text_mt_dds;
416         }
417         if (!strcmp(argv[0] + l - 6, "dds-dd")) {
418                 pg = DDS_DD;
419                 help_text = help_text_dds_dd;
420         }
421
422         /*
423          * Scanning the environment.
424          */
425         p = getenv("DDS2TAR");
426         while (p != NULL) {
427                 int count = 0 ;
428                 if (*p == ' ') p++;
429                 if ( *p == '\0' ) p = NULL ;
430                 else if (strprefix(&p, "-z","--compress")) {
431                         compressed_mode = C_MODE;
432                 } else if (strprefix(&p, "--first-block ","-s")) {
433                         sscanf(p, "%d%n", &tar_fb, &count);
434                         p += count;
435                 } else if (strprefix(&p, "--block-size ","-b ")){
436                         sscanf(p, "%d%n", &tar_bs, &count);
437                         tar_n = tar_bs * 512 ;
438                         buf_n = tar_n ;
439                         p += count;
440                 } else if (strprefix(&p, "--Block-size ","-B ")){
441                         sscanf(p, "%d%n", &tar_bs, &count);
442                         tar_n = tar_bs * 512 ;
443                         buf_n = tar_n ;
444                         p += count;
445                         density = tar_n ;
446                 } else
447                         p = NULL;
448         }
449
450         /*
451          * scan arguments
452          */
453         while (n < argc) {
454
455                 /*
456                  * Macros to test arguments ...
457                  */
458
459 #define T1(s)        if((!strcmp(argv[n],(s))))
460 #define T(s)    else if((!strcmp(argv[n],(s))))
461 #define TT(s,t) else if((!strcmp(argv[n],(s)))||(!strcmp(argv[n],(t))))
462 #define ELSE    else
463 #define ELSEIF(s) else if(s)
464
465                 /*
466                  * Now scanning the arguments ...
467                  */
468
469                 T1("-0") {
470                         fprintf(stdout, "dds2tar: %s\n", argv[0]);
471                         exit(0);
472                 }
473
474                 /*
475                  * misc
476                  */
477                 T("--help") {
478                         fprintf(stdout, help_text);
479                         exit(0);
480                 }
481                 TT("--version", "-V") {
482                         fprintf(stdout, "%s: %s\n", pg, version);
483                         exit(0);
484                 }
485
486                 /*
487                  * Some more options ...
488                  */
489                 TT("--verbose", "-v") verbose = 1;
490                 T("--hash-mode") hash_mode = 1;
491                 T("--force") force_nochk = 1;
492
493                 /*
494                  * device name
495                  */
496                 T("-f") device_name = argv[++n];
497
498                 /*
499                  * index file
500                  */
501                 TT("-z", "--compress") compressed_mode = C_MODE;
502                 TT("--z", "--no-compress") compressed_mode = T_MODE;
503                 TT("-t", "--table-of-contents") {
504                         index_file = argv[++n];
505                         /*
506                          * The format of the index is checked by the program.
507                          */
508                 }
509
510                 /*
511                  * Location of the file
512                  */
513                 TT("-s", "--first-block") {
514                         tar_fb = atoi(argv[++n]);
515                 }
516                 TT("-b", "--block-size") {
517                         tar_bs = atoi(argv[++n]);
518                         tar_n = tar_bs * 512 ;
519                         buf_n = tar_n ;
520                 }
521                 TT("-B", "--Block-size") {
522                         tar_bs = atoi(argv[++n]);
523                         tar_n = tar_bs * 512 ;
524                         buf_n = tar_n ;
525                         density = tar_n ;
526                 }
527                 TT("-m", "--buffer-size") {
528                         fprintf(stderr,"buffer size is %d records, %d bytes\n",
529                                 buf_n>>9,buf_n);
530                         exit(0);
531                 }
532
533                 ELSEIF(pg == DDS2TAR) {
534                         /*
535                          * Mode of the program.
536                          *
537                          * If you install dds2tar as mt-dds, the program will
538                          * act as mt-dds. Since for some operations you need
539                          * root permissions on mt-dds, it would not be a good
540                          * idea to let the user switch to dds2index or dds2tar
541                          * in this case.
542                          */
543
544                         T1("--dds2index") {
545                                 pg = DDS2INDEX;
546
547                                 help_text = help_text_dds2index;
548                         }
549                         T("--mt-dds") {
550                                 pg = MTDDS;
551                                 help_text = help_text_mt_dds;
552                         }
553                         T("--dds-dd") {
554                                 pg = DDS_DD;
555                                 help_text = help_text_dds_dd;
556                         }
557                         /*
558                          * Mode of extraction ...
559                          *
560                          * The location list an experimental mode.
561                          */
562 #ifdef EXP_STUFF
563                         T("--location-list") {
564                                 pattern_list = argv + n + 1;
565                                 mode = LOCATION;
566                                 break;
567                         }
568 #endif
569                         /*
570                          * Select a file for the output.
571                          *
572                          * Since mt-dds may be run as root, we write on screen
573                          * in this case. Writing to a file is supported for
574                          * dds2tar.
575                          */
576                         TT("-o", "--output") {
577                                 reopen(1, argv[++n], O_WRONLY | O_CREAT, 0660);
578                         }
579
580                         /*
581                          * Do not read anything from tape.
582                          */
583                         TT("-l", "--list") {
584                                 list_only = 1;
585                                 if (verbose)
586                                         fputs("--list\n", stderr);
587                         }
588                         /*
589                          * Write only the body of the file.
590                          */
591                         T("--body"){
592                                 write_body = 1 ;
593                         }
594
595                         /*
596                          * Don't extract the parent directories from the tape.
597                          */
598                         TT("-q","--quick"){
599                                 quick_mode = 1 ;
600                         }
601                         /*
602                          * Pipe the output to tar -x.
603                          *
604                          * This is for testing only.
605                          */
606                         T("--test") {
607                                 static char const *const a[5] =
608                                 {
609                                         "/bin/tar", "tfb", "-", "1", NULL
610                                 };
611
612                                 child_proc = creopen(1, 0, a[0], a);
613                         }
614                         T("--test-verbose") {
615                                 static char const *const a[5] =
616                                 {
617                                         "/bin/tar", "tfbv", "-", "1", NULL
618                                 };
619
620                                 child_proc = creopen(1, 0, a[0], a);
621                         }
622                         T("--extract") {
623                                 static char const *const a[5] =
624                                 {
625                                         "/bin/tar", "xfb", "-", "1", NULL
626                                 };
627
628                                 child_proc = creopen(1, 0, a[0], a);
629                         }
630                         ELSE {
631                                 {
632                                         char*const*p = argv+n ;
633                                         while (*p) dds_unquote(*p++) ;
634                                 }
635                                 pattern_list = (const char*const*)argv + n;
636                                 if (verbose)
637                                         fprintf(stderr,
638                                                 "first pattern is '%s'\n",
639                                                 *pattern_list
640                                                 );
641                                 mode = EXTRACT;
642                                 break;
643                         }
644                 }
645
646                 ELSEIF(pg == MTDDS) {
647                         /*
648                          * Tape actions ...
649                          */
650                         T1("tell") print_location = 1;
651                         T("label") get_label = 1 ;
652                         T("filename") get_filename = 1 ;
653                         T("bs") get_blocksize = 1 ;
654                         T("date") {
655                                 get_date = 1 ;
656                                 if ( argc > 2 ) {
657                                         int j = atoi(argv[2]);
658                                         fputs(ctime((time_t*)&j),stdout);
659                                         exit(0);
660                                 }
661                         }
662                         T("ts") get_timestamp = 1 ;
663                         T("blksize") print_blksize = 1 ;
664 #ifdef HPDAT
665 #define R(c) if ( 0 != geteuid() ) { fprintf(stderr,\
666 "You have to be root to do this : %s\n",c);exit(1);}
667                         T("comp-on") {
668                                 R("comp-on");
669                                 mt_action = DDSCM_ON;
670                         }
671                         T("comp-off") {
672                                 R("comp-off");
673                                 mt_action = DDSCM_OFF;
674                         }
675                         T("comp-query") {
676                                 R("comp-query");
677                                 mt_action = DDSCM_QUERY;
678                         }
679                         T("comp-log") {
680                                 R("comp-log");
681                                 mt_action = DDSCM_LOG;
682                         }
683                         T("load") {
684                                 R("comp-load");
685                                 mt_action = DDSCM_LOAD;
686                         }
687                         T("unload") {
688                                 R("comp-unload");
689                                 mt_action = DDSCM_UNLOAD;
690                         }
691                         T("where") {
692                                 mt_action = DDSCM_WHERE;
693                         }
694                         /*
695                          * Set mode scsi2logical first
696                          */
697                         T("scsi2logical"){
698                                 mt_action = DDSCM_LOGICAL;
699                         }
700
701 #endif
702 #ifdef EXP_STUFF
703                         /*
704                  * tar-dds will handle the arguments in a very different way.
705                  */
706                 }
707                 ELSEIF(pg == TAR_DDS) {
708
709                         break;
710 #endif
711                 }
712                 /*
713                  * Next argument ...
714                  */
715                 n++;
716         }
717
718         cur_block = malloc(buf_n);
719         cur_line = malloc(MAXPATHLEN<<2);
720         if (cur_block == NULL || cur_line == NULL) {
721                 fprintf(stderr, "%s: No memory available.\n", pg);
722                 exit(2);
723         }
724         /*
725          * Switch the program mode ... dds2tar, dds2index or mt-dds ...
726          */
727         /*---------------------MT-DDS--------------------------------*/
728         if (pg == MTDDS) {
729 #ifdef HPDAT
730                 /*
731                  * Is setting of compression mode or log page selected ?
732                  *
733                  * I think you have to run this as root.
734                  */
735                 if (mt_action != DDSCM_NULL) {
736                         device = open_device(device_name, O_WRONLY);
737                         if ( mt_action == DDSCM_LOGICAL )
738                                 dds_scsi2logical();
739                         else
740                         if ( mt_action == DDSCM_WHERE ) {
741                                 tar_fb = dds_getpos(device);
742                                 printf(" -s %d \n", tar_fb);
743                                 close(device);
744                                 return 0;
745                         } else
746                                 set_compression_mode(device, mt_action);
747                 } else
748 #endif
749                 /*
750                  * Print the current position (tree lines).
751                  */
752                 {
753                         device = open_device(device_name, O_RDONLY);
754                         if ( vid == HP ){
755                                 tar_fb = dds_getpos(device);
756                                 dds_read_next_block();
757                                 /* dds_seek(device, tar_fb); */
758                                 dds_bsr();
759                         } else {
760                                 tar_fb = dds_getpos(device);
761                                 cur_n = tar_n ;
762                         }
763                         tar_bs = cur_n >> 9;
764                         if (( get_label || get_timestamp ||
765                                 get_date || get_filename ) &&
766                                 ( dds_is_tar_header_record(cur_block) != 0 )) {
767                                 if ( cur_block->hdr.linkflag == 'V' ) {
768                                         int i , j = 0 ;
769                                         char*p=cur_block->hdr.mtime ;
770                                         for ( i = 0 ; i < 12 ; i++ ) {
771                                                 if ((p[i]>='0')&&(p[i]<='7')) {
772                                                         j <<= 3 ;
773                                                         j += p[i] - '0' ;
774                                                 }
775                                         }
776                                         if ( get_label )
777                                                 puts(cur_block->hdr.name);
778                                         else if ( get_timestamp ){
779                                                 printf("%d\n",j);
780                                         } else /* get_date */ {
781                                                 fputs(ctime((time_t*)&j),stdout);
782                                         }
783                                 } else
784                                 if ( get_filename ) puts(cur_block->hdr.name);
785                         } else
786                         if (print_location != 0) {
787                                 printf(dds_loctext, tar_fb, tar_bs, cur_n);
788                         } else
789                         if ( print_blksize != 0 ) {
790                                 printf("%d\n",tar_bs);
791                         } else {
792                                 /*
793                                  * Print the current position (one line).
794                                  */
795                                 printf(" -s %d -b %d \n", tar_fb, tar_bs);
796                         }
797                 }
798                 close(device);
799                 /*---------------------DDS2TAR-------------------------------*/
800         } else if (pg == DDS2TAR) {
801
802                 if (pattern_list == NULL)
803                         return 0;
804                 if (list_only != 1) {
805                         device = open_device(device_name, O_RDONLY);
806
807                         if ( density ) dds_set_bs(density);
808                 }
809                 index_fp = zfopen(index_file, compressed_mode, "r");
810                 switch (mode) {
811 #ifdef EXP_STUFF
812                 case LOCATION:
813                         extract_loc(pattern_list);
814                         break;
815 #endif
816                 case EXTRACT:
817                         dds_cmp(pattern_list);
818                         break;
819                 default:
820                         fprintf(stderr, "nothing to do ? Try --help\n");
821                 }
822                 if (list_only != 1)
823                         close(device);
824                 if (child_proc != -1)
825                         cclose(1);
826                 /*---------------------DDS2INDEX-----------------------------*/
827         } else if (pg == DDS2INDEX) {
828                 device = open_device(device_name, O_RDONLY);
829                 if ( density ) dds_set_bs(density);
830                 index_fp = zfopen(index_file, compressed_mode, "w");
831                 dds_index();
832                 close(device);
833                 /*-----------------------------------------------------------*/
834         } else if ( pg == DDS_DD ) {
835                 device = open_device(device_name, O_RDONLY);
836                 if ( density ) dds_set_bs(density);
837                 if ( verbose ) fprintf(stderr,"dds-dd ...\n");
838                 while ( dds_read_next_block() , cur_n )
839                         fwrite(cur_block,1,cur_n,stdout);
840         } else {
841                 fprintf(stderr, "no program mode \n");
842                 /*-----------------------------------------------------------*/
843         }
844         return 0;
845 }
846