Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / wodim / clone.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)clone.c  1.7 04/03/02 Copyright 2001-2004 J. Schilling */
14 /*
15  *      Clone Subchannel processing
16  *
17  *      Copyright (c) 2001-2004 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include <mconfig.h>
35 #include <stdio.h>
36 #include <fctldefs.h>
37 #include <strdefs.h>
38 #include <unixstd.h>
39 #include <standard.h>
40 #include <btorder.h>
41 #include <utypes.h>
42 #include <schily.h>
43
44 #include <usal/usalcmd.h>
45 #include <usal/scsitransp.h>
46
47 #include "wodim.h"
48 #include "crc16.h"
49
50 #include <usal/scsireg.h>
51 #include "scsimmc.h"
52
53 /*#define       SAO_RAW*/
54
55 void    clone_toc(track_t *trackp);
56 void    clone_tracktype(track_t *trackp);
57
58 extern  int     lverbose;
59 extern  int     xdebug;
60
61 extern  Uchar   _subq[110][12];
62 extern  int     _nsubh;
63
64
65 static  int     ctrl_first;
66 static  int     ctrl_last;
67 static  int     sectype_first;
68 static  int     sectype_last;
69 static  int     disktype;
70 static  long    loutstart;
71
72 /*
73  * Read Clone TOC description from full toc file.
74  */
75 void clone_toc(track_t *trackp)
76 {
77         char    filename[1024];
78         msf_t   m;
79         msf_t   mr;
80         struct  tocheader *tp;
81         struct  ftrackdesc *fp;
82         int     f;
83         char    buf[2048];
84         int     amt;
85         int     len;
86         int     i;
87         int     j;
88         int     ctrladr;
89         Uint    first = 100;
90         Uint    last = 0;
91
92         len = strlen(trackp[1].filename);
93         if (len > (sizeof (filename)-5)) {
94                 len = sizeof (filename)-5;
95         }
96         snprintf(filename, sizeof (filename), "%.*s.toc", len, trackp[1].filename);
97
98         f = open(filename, O_RDONLY|O_BINARY);
99         if (f < 0)
100                 comerr("Cannot open '%s'.\n", filename);
101         amt = read(f, buf, sizeof (buf));
102
103         if (amt == sizeof (buf))
104                 comerrno(EX_BAD, "TOC too large.\n");
105         close(f);
106         tp = (struct tocheader *)buf;
107         len = a_to_u_2_byte(tp->len) + sizeof (struct tocheader)-2;
108
109         if (xdebug) {
110                 printf("Read %d bytes TOC len: %d first session: %d last session: %d\n",
111                         amt, len, tp->first, tp->last);
112         }
113
114         fp = (struct ftrackdesc *)&buf[4];
115
116         for (i = 4, j = 0; i < len; i += 11) {
117                 fp = (struct ftrackdesc *)&buf[i];
118                 if (xdebug)
119                         usal_prbytes("FT", (Uchar *)&buf[i], 11);
120                 if (fp->sess_number != 1)
121                         comerrno(EX_BAD, "Can only copy session # 1.\n");
122
123                 if (fp->adr == 1) {
124                         if (fp->point < first) {
125                                 first = fp->point;
126                                 ctrl_first = fp->control;
127                         }
128                         if (fp->point <= 99 && fp->point > last) {
129                                 last = fp->point;
130                                 ctrl_last = fp->control;
131                         }
132                 }
133                 if (fp->adr != 1) {
134                         switch (fp->point) {
135
136                         case 0xB0:
137                         case 0xC0:
138                         case 0xC1:
139                                 break;
140                         default:
141                                 continue;
142                         }
143                 }
144                 m.msf_min    = fp->amin;
145                 m.msf_sec    = fp->asec;
146                 m.msf_frame  = fp->aframe;
147
148                 mr.msf_min   = fp->pmin;
149                 mr.msf_sec   = fp->psec;
150                 mr.msf_frame = fp->pframe;
151
152                 if (fp->point == 0xA0) {
153                         disktype = mr.msf_sec;
154                         mr.msf_sec = from_bcd(mr.msf_sec);              /* convert to BCD */
155                 }
156
157                 if (fp->point == 0xA2)
158                         loutstart = msf_to_lba(fp->pmin, fp->psec, fp->pframe, TRUE);
159                 ctrladr = fp->control << 4;
160                 ctrladr |= fp->adr;
161
162                 filltpoint(_subq[j], ctrladr, fp->point, &mr);
163                 fillttime(_subq[j], &m);
164                 _subq[j][6] = fp->res7;
165                 if (fp->point == 0xC0 || fp->point == 0xC1) {
166                         _subq[j][3] = m.msf_min;
167                         _subq[j][4] = m.msf_sec;
168                         _subq[j][5] = m.msf_frame;
169                 }
170                 if (fp->point == 0xC1) {
171                         _subq[j][7] = mr.msf_min;
172                         _subq[j][8] = mr.msf_sec;
173                         _subq[j][9] = mr.msf_frame;
174                 }
175                 if (xdebug)
176                         usal_prbytes("TOC  ", _subq[j], 12);
177                 j++;
178         }
179         _nsubh = j;
180         if (xdebug) {
181                 printf("nsubheader %d lout: %ld track 1 secs: %ld\n", j, loutstart, trackp[1].tracksecs);
182                 printf("first %u last %u ctrl first: %X ctrl last %X\n", first, last, ctrl_first, ctrl_last);
183         }
184         if (trackp->tracks != 1)
185                 comerrno(EX_BAD, "Clone writing currently supports only one file argument.\n");
186         if (loutstart > trackp[1].tracksecs)
187                 comerrno(EX_BAD, "Clone writing TOC length %ld does not match track length %ld\n",
188                         loutstart, trackp[1].tracksecs);
189
190         if (amt > len) {
191                 sectype_first = buf[len];
192                 sectype_last = buf[len+1];
193                 if (xdebug) {
194                         printf("sectype first: %X sectype last %X\n",
195                                 sectype_first, sectype_last);
196                 }
197         }
198 }
199
200
201 /*
202  * Set tracktypes for track 0 (lead-in) & track AA (lead-out)
203  *
204  * Control 0 = audio
205  * Control 1 = audio preemp
206  * Control 2 = audio copy
207  * Control 3 = audio copy preemp
208  * Control 4 = data
209  * Control 5 = packet data
210  */
211 void clone_tracktype(track_t *trackp)
212 {
213         int     tracks = trackp->tracks;
214         int     sectype;
215
216         sectype = SECT_ROM;
217         if ((ctrl_first & TM_DATA) == 0) {
218                 sectype = SECT_AUDIO;
219
220                 if ((ctrl_first & TM_PREEM) != 0) {
221                         trackp[0].flags |= TI_PREEMP;
222                 } else {
223                         trackp[0].flags &= ~TI_PREEMP;
224                         sectype |= ST_PREEMPMASK;
225                 }
226                 if ((ctrl_first & TM_ALLOW_COPY) != 0) {
227                         trackp[0].flags |= TI_COPY;
228                 } else {
229                         trackp[0].flags &= ~TI_COPY;
230                 }
231 /* XXX ???      flags |= TI_SCMS; */
232         } else {
233                 if ((ctrl_first & TM_INCREMENTAL) != 0) {
234                         trackp[0].flags |= TI_PACKET;
235                 } else {
236                         trackp[0].flags &= ~TI_PACKET;
237                 }
238                 if (sectype_first != 0)
239                         sectype = sectype_first;
240         }
241         trackp[0].sectype = sectype;
242
243         sectype = SECT_ROM;
244
245         if ((ctrl_last & TM_DATA) == 0) {
246                 sectype = SECT_AUDIO;
247
248                 if ((ctrl_last & TM_PREEM) != 0) {
249                         trackp[tracks+1].flags |= TI_PREEMP;
250                 } else {
251                         trackp[tracks+1].flags &= ~TI_PREEMP;
252                         sectype |= ST_PREEMPMASK;
253                 }
254                 if ((ctrl_last & TM_ALLOW_COPY) != 0) {
255                         trackp[tracks+1].flags |= TI_COPY;
256                 } else {
257                         trackp[tracks+1].flags &= ~TI_COPY;
258                 }
259 /* XXX ???      flags |= TI_SCMS; */
260         } else {
261                 if ((ctrl_first & TM_INCREMENTAL) != 0) {
262                         trackp[0].flags |= TI_PACKET;
263                 } else {
264                         trackp[0].flags &= ~TI_PACKET;
265                         if (sectype_last != 0)
266                                 sectype = sectype_last;
267                 }
268         }
269         trackp[tracks+1].sectype = sectype;
270 }