add a config file git-buildpackage
[debian/dds2tar] / dds_index.c
1
2 /*
3  * This file is part of dds2tar.
4  * Copyright by J"org Weule
5  */
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <sys/mtio.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include "dds2tar.h"
13 #include "dds_tape.h"
14
15 static int              cur_rec;
16 static int              cur_byte;
17 static const    char    hash_sign = '#';
18
19 /********
20         * Skip to the next block.
21         *
22         ********************************************************************/
23 void dds_index_skip(){
24         /*
25          * The hp-DAT is slowed down with dds_getpos().
26                 * Is there a reason for this?
27          *
28          * Now the cur_blkno is incremented.
29          */
30         cur_rec -= cur_bs;
31         dds_read_next_block();
32         cur_byte += cur_n;
33         if (hash_mode == 1)
34                 if ((cur_blkno & 0x1f) == 0) {
35                         if ((cur_blkno & 0x7ff) == 0) {
36                                 fprintf(stderr, " %d\n",cur_byte);
37                                 fflush(stderr);
38                         }
39                         write(2, &hash_sign, 1);
40                 }
41 }
42
43 /********
44         * Converting a tar-record to an entry in the index file.
45         *
46         *  input: tar_record is the header of one file in the archive.
47         *         The location of the header is given by the
48         *         block and index value.
49         * output: The returned index is the location of the next header.
50         *         Normalization of the pair (block,rec) with respect to
51         *         the block length will give the right position.
52         * extern: index_fp, verbose
53         *         index_fp is the FILE to write the rec.
54         *         verbose indicates the loggin mode.
55         *
56         *         If the name length of the file name is zero,
57         *         and an empty block is found, the end
58         *         of the archive is found and the program stops.
59         *
60         ********************************************************************/
61 static int
62 dds_index_h(tar_record *const ptr, int const block, int rec)
63 {
64         int     size;
65         char   *p = ptr->hdr.magic;
66
67 #ifdef DDS_TRACE
68         fputs("dds_index_h()\n", stderr);
69 #endif
70
71         if ( dds_is_tar_header_record(ptr) == 0 ) {
72                 fprintf(stderr,"dds2index: skipping to next header\n");
73                 return ( rec + 1 ) ;
74         }
75
76         if (*p == 0)
77                 p = "magic ";
78         if (ptr->hdr.linkflag == 'V') p = "label ";
79         else if (p[6] == ' ')
80                 p[6] = 0;
81         if (ptr->hdr.name[0] == 0) {
82                 int     i = 0;
83
84                 while ((((char *) ptr)[i] == 0) && (i < 512))
85                         i++;
86                 if (i == 512) {
87                         fprintf(index_fp, dds_index_format,
88                                 "-end- ",
89                                 block,
90                                 rec,
91                                 0, "(null)");
92                         close(device);
93                         exit(0);
94                 }
95         }
96         if (ptr->hdr.size[0] != 0)
97                 sscanf(ptr->hdr.size, "%o", &size);
98         else
99                 size = 0;
100         long_name_len = 0 ;
101         if ( ptr->hdr.linkflag == LF_LONGNAME ) long_name_len = size ;
102                 
103         {
104                 char *name = ptr->hdr.name ;
105                 if ( ptr->hdr.linkflag != LF_LONGLINK &&
106                      ptr->hdr.linkflag != LF_LONGNAME &&
107                         long_name[0] != '\0' ) name = long_name ;
108                 sprintf(cur_line, dds_index_format,
109                         p,
110                         block,
111                         rec,
112                         size,
113                         name
114                         );
115                 fputs(cur_line, index_fp);
116                 if ( ptr->hdr.linkflag != LF_LONGLINK &&
117                      ptr->hdr.linkflag != LF_LONGNAME ) {
118                         long_name[0] = '\0' ;
119                 }
120         }
121         if (verbose)
122                 fputs(cur_line, stderr);
123         /* calculate the number of records */
124         /* there was one header record */
125         size += 511 + 512;
126         size >>= 9;
127         rec += size;
128         return rec;
129 }
130
131 /********
132         * Converting a table line to the numbers.
133         *
134         */
135 int
136 rt_line(
137                int *const ptr_blkno,
138                int *const ptr_recno,
139                int *const ptr_size,
140                char **const ptr_name
141 )
142 {
143         char    p[16];
144         int     i;
145         char    const *dds_fmt = NULL;
146
147 #ifdef DDS_TRACE
148         fprintf(stderr,"rt_line(...)\n");
149 #endif
150
151         if (cur_line[16] == ':') {
152                 dds_fmt = dds_old_index_scan_format ;
153                 *ptr_name = cur_line + 27;
154         } else {
155                 if (cur_line[17] == ':') {
156                         dds_fmt = dds_index_scan_format ;
157                         *ptr_name = cur_line + 28;
158                 } else return 1 ;
159         } ;
160
161         if ((i = sscanf(cur_line,
162                         dds_fmt,
163                         p,
164                         ptr_blkno,
165                         ptr_recno,
166                         ptr_size)) < 4)
167                 fprintf(stderr, "Wrong line inside the index file,"
168                         " scanned %d values\n", i);
169 #ifdef DDS_TRACE
170         fprintf(stderr,"end >> rt_line(...)\n");
171 #endif
172         return 0 ;
173 }
174
175 /* procedure to create the index table */
176 /********
177         *  input: none
178         * output: none
179         * extern: device, index_fp
180         *
181         * The archive is read, and the index file is written.
182         *
183         ************************************************************/
184
185 int
186 dds_index(void)
187 {
188
189
190 #ifdef DDS_TRACE
191         fputs("dds_index()\n", stderr);
192 #endif
193
194
195         fputs(dds_headline, index_fp);
196         if (verbose) fputs(dds_headline, index_fp);
197         next_blkno = -1 ;
198         cur_rec = 0;
199         dds_read_block();
200         cur_byte = cur_n;
201         if (hash_mode == 1)
202                 if ((cur_blkno & 0x1f) == 0) {
203                         write(2, &hash_sign, 1);
204                 }
205         while (cur_n > 0) {
206                 cur_bs = cur_n >> 9;
207                 while (cur_rec < cur_bs) {
208                         int new_rec ;
209                         new_rec = dds_index_h(
210                                                      cur_block + cur_rec,
211                                                      cur_blkno,
212                                                      cur_rec
213                                 );
214                         if ( long_name_len > 0 ) {
215                                 int i = 0 ;
216                                 while ( long_name_len > (i<<9) ){
217                                         cur_rec++;
218                                         /*
219                                          * note: dds_index_skip operates on
220                                          *       cur_rec
221                                          */
222                                         if ( cur_rec >= cur_bs )
223                                                 dds_index_skip();
224                                         memcpy(long_name+((i++)<<9),
225                                                 cur_block+cur_rec,
226                                                 512);
227                                 }
228                                 long_name_len = 0 ;
229                                 /* Now go to the next block behind the
230                                    long name */
231                                 cur_rec++;
232                         }
233                         else cur_rec = new_rec ;
234                 }
235                 dds_index_skip();
236         }
237         if (cur_n <= 0) {
238                 perror("dds2tar");
239                 fprintf(stderr, "dds_index: unexpected end of tar archive \n");
240                 close(device);
241                 exit(9);
242         }
243         return 0;
244 }
245