29 #include <stdio.h> |
29 #include <stdio.h> |
30 #include <unistd.h> |
30 #include <unistd.h> |
31 #include <fcntl.h> |
31 #include <fcntl.h> |
32 #include <string.h> |
32 #include <string.h> |
33 #include <linux/cdrom.h> |
33 #include <linux/cdrom.h> |
|
34 #include <linux/fs.h> |
34 #include <sys/ioctl.h> |
35 #include <sys/ioctl.h> |
35 |
36 |
|
37 #include "cdrom.h" |
36 #include "cdbackup.h" |
38 #include "cdbackup.h" |
37 #include "misc.h" |
39 #include "misc.h" |
|
40 #include "debug.h" |
38 |
41 |
39 /* size of leadin/out depending of how many tracks are on cd */ |
42 /* size of leadin/out depending of how many tracks are on cd */ |
40 #define MIN_FREE_1 (11400*CD_FRAMESIZE) /* 1th track */ |
43 #define MIN_FREE_1 (11400*CD_FRAMESIZE) /* 1th track */ |
41 #define MIN_FREE_2 (6900*CD_FRAMESIZE) /* 2nd and more tracks */ |
44 #define MIN_FREE_2 (6900*CD_FRAMESIZE) /* 2nd and more tracks */ |
|
45 /* number of (unreadable) runout sectos */ |
|
46 #define RUNOUT 2 |
42 |
47 |
43 struct toc_entry *toc=0; |
48 struct toc_entry *toc=0; |
44 long long cd_used, cd_avail; |
49 long long cd_used, cd_avail; |
45 |
50 |
46 extern long cd_len; |
51 extern long cd_len; |
57 /****************************************************************************/ |
62 /****************************************************************************/ |
58 |
63 |
59 void close_cdr(int cd_fd) |
64 void close_cdr(int cd_fd) |
60 { |
65 { |
61 close(cd_fd); |
66 close(cd_fd); |
|
67 } |
|
68 |
|
69 /****************************************************************************/ |
|
70 |
|
71 void get_param(int fd, unsigned long *ahead, unsigned long *fahead) |
|
72 { |
|
73 #if defined(BLKRAGET) && defined(BLKFRAGET) |
|
74 *ahead = *fahead = 0; |
|
75 ioctl(fd,BLKRAGET,ahead); |
|
76 ioctl(fd,BLKFRAGET,fahead); |
|
77 DEBUG("get_param: readahead=%ld freadahead=%ld\n",*ahead,*fahead); |
|
78 #else |
|
79 fprintf("Can't get readahead parameter. Ioctl's not available\n"); |
|
80 #endif |
|
81 } |
|
82 |
|
83 /****************************************************************************/ |
|
84 |
|
85 void set_param(int fd, unsigned long ahead, unsigned long fahead) |
|
86 { |
|
87 #if defined(BLKRAGET) && defined(BLKFRAGET) |
|
88 ioctl(fd, BLKRASET, ahead); |
|
89 ioctl(fd, BLKFRASET, fahead); |
|
90 DEBUG("set_param: readahead=%ld freadahead=%ld\n",ahead,fahead); |
|
91 #else |
|
92 fprintf("Can't set readahead parameter. Ioctl's not available\n"); |
|
93 #endif |
62 } |
94 } |
63 |
95 |
64 /****************************************************************************/ |
96 /****************************************************************************/ |
65 |
97 |
66 int full_read(int fd, void *buf, int count) |
98 int full_read(int fd, void *buf, int count) |
99 } |
131 } |
100 |
132 |
101 /* get start and end tracks */ |
133 /* get start and end tracks */ |
102 start_track = cd_header.cdth_trk0; |
134 start_track = cd_header.cdth_trk0; |
103 tracks = cd_header.cdth_trk1-start_track+1; |
135 tracks = cd_header.cdth_trk1-start_track+1; |
|
136 DEBUG("read_toc: starttrack=%d tracks=%d\n",start_track,tracks); |
104 |
137 |
105 free_toc(); |
138 free_toc(); |
106 if(!(toc=calloc(tracks+1,sizeof(struct toc_entry)))) serror("No memory for TOC"); |
139 if(!(toc=calloc(tracks+1,sizeof(struct toc_entry)))) serror("No memory for TOC"); |
107 |
140 |
108 /* set some parameters */ |
141 /* set some parameters */ |
113 if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading lead-out"); |
146 if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading lead-out"); |
114 |
147 |
115 toc[0].track_no=CDROM_LEADOUT; /* not a real track */ |
148 toc[0].track_no=CDROM_LEADOUT; /* not a real track */ |
116 toc[0].sec_start=cd_entry.cdte_addr.lba; |
149 toc[0].sec_start=cd_entry.cdte_addr.lba; |
117 |
150 |
118 cd_used=(long long)toc[0].sec_start*CD_FRAMESIZE; cd_avail=(long long)cd_len*CD_FRAMESIZE-cd_used; |
151 cd_used =(long long)toc[0].sec_start*CD_FRAMESIZE; |
|
152 cd_avail =(long long)cd_len*CD_FRAMESIZE-cd_used; |
119 cd_avail-=(tracks>1?MIN_FREE_2:MIN_FREE_1); |
153 cd_avail-=(tracks>1?MIN_FREE_2:MIN_FREE_1); |
|
154 DEBUG("read_toc: cd_used=%lld (%lld secs) cd_avail=%lld (%lld secs)\n",cd_used,cd_used/CD_FRAMESIZE,cd_avail,cd_avail/CD_FRAMESIZE); |
|
155 |
120 if(cd_avail<0) cd_avail=0; /* can be <0 due to assumed additional lead-in/out */ |
156 if(cd_avail<0) cd_avail=0; /* can be <0 due to assumed additional lead-in/out */ |
121 |
157 |
122 /* read rest of tracks */ |
158 /* read rest of tracks */ |
123 for(i=1; i<=tracks; i++) { |
159 for(i=1; i<=tracks; i++) { |
124 cd_entry.cdte_track=start_track+i-1; |
160 cd_entry.cdte_track=start_track+i-1; |
126 |
162 |
127 toc[i].track_no=start_track+i-1; |
163 toc[i].track_no=start_track+i-1; |
128 toc[i].sec_start=cd_entry.cdte_addr.lba; |
164 toc[i].sec_start=cd_entry.cdte_addr.lba; |
129 if(cd_entry.cdte_ctrl&CDROM_DATA_TRACK) toc[i].is_data=1; |
165 if(cd_entry.cdte_ctrl&CDROM_DATA_TRACK) toc[i].is_data=1; |
130 } |
166 } |
|
167 |
|
168 /* calculate end sectors */ |
|
169 toc[tracks].sec_end = toc[ 0].sec_start - 1 - RUNOUT; |
|
170 for(i=1; i<tracks; i++) |
|
171 toc[i].sec_end = toc[i+1].sec_start - 1 - RUNOUT - (i>1?(MIN_FREE_2/CD_FRAMESIZE):(MIN_FREE_1/CD_FRAMESIZE)); |
131 |
172 |
132 if(trackinfos) |
173 if(trackinfos) |
133 /* now loop through tracks and read header info */ |
174 /* now loop through tracks and read header info */ |
134 for(i=1; i<=tracks; i++) { |
175 for(i=1; i<=tracks; i++) { |
135 char inbuffer[CD_FRAMESIZE]; |
176 char inbuffer[CD_FRAMESIZE]; |