1.1 --- a/cdrom.c Sat Dec 29 15:23:55 2007 +0100
1.2 +++ b/cdrom.c Sat Dec 29 15:25:21 2007 +0100
1.3 @@ -1,5 +1,5 @@
1.4 /* cdrom.c
1.5 -Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
1.6 +Copyright (c) 2000-2004 Craig Condit, Stefan Hülswitt.
1.7
1.8 Redistribution and use in source and binary forms, with or without
1.9 modification, are permitted provided that the following conditions are met:
1.10 @@ -27,47 +27,28 @@
1.11
1.12 #include <stdlib.h>
1.13 #include <stdio.h>
1.14 -#include <unistd.h>
1.15 -#include <fcntl.h>
1.16 -#include <string.h>
1.17 -#include <linux/cdrom.h>
1.18 -#include <linux/fs.h>
1.19 #include <sys/ioctl.h>
1.20
1.21 +#ifdef linux
1.22 +#include <linux/fs.h>
1.23 +#endif
1.24 +
1.25 #include "cdrom.h"
1.26 -#include "cdbackup.h"
1.27 #include "misc.h"
1.28 #include "debug.h"
1.29
1.30 /* size of leadin/out depending of how many tracks are on cd */
1.31 -#define MIN_FREE_1 (11400*CD_FRAMESIZE) /* 1th track */
1.32 -#define MIN_FREE_2 (6900*CD_FRAMESIZE) /* 2nd and more tracks */
1.33 +#define LEADOUT_1 11400 /* 1th track */
1.34 +#define LEADOUT_2 6900 /* 2nd and more tracks */
1.35 /* number of (unreadable) runout sectos */
1.36 #define RUNOUT 2
1.37
1.38 -struct toc_entry *toc=0;
1.39 -long long cd_used, cd_avail;
1.40 -
1.41 -extern long cd_len;
1.42 +extern int fd;
1.43 extern int verbose;
1.44 extern char *prg_name;
1.45
1.46 /****************************************************************************/
1.47
1.48 -int open_cdr(char *device)
1.49 -{
1.50 - return open(device, O_RDONLY | O_NONBLOCK);
1.51 -}
1.52 -
1.53 -/****************************************************************************/
1.54 -
1.55 -void close_cdr(int cd_fd)
1.56 -{
1.57 - close(cd_fd);
1.58 -}
1.59 -
1.60 -/****************************************************************************/
1.61 -
1.62 void get_param(int fd, unsigned long *ahead, unsigned long *fahead)
1.63 {
1.64 #if defined(BLKRAGET) && defined(BLKFRAGET)
1.65 @@ -76,7 +57,7 @@
1.66 ioctl(fd,BLKFRAGET,fahead);
1.67 DEBUG("get_param: readahead=%ld freadahead=%ld\n",*ahead,*fahead);
1.68 #else
1.69 - fprintf("Can't get readahead parameter. Ioctl's not available\n");
1.70 + fprintf(stderr,"Can't get readahead parameter. Ioctl's not available\n");
1.71 #endif
1.72 }
1.73
1.74 @@ -85,125 +66,52 @@
1.75 void set_param(int fd, unsigned long ahead, unsigned long fahead)
1.76 {
1.77 #if defined(BLKRAGET) && defined(BLKFRAGET)
1.78 - ioctl(fd, BLKRASET, ahead);
1.79 - ioctl(fd, BLKFRASET, fahead);
1.80 + ioctl(fd,BLKRASET,ahead);
1.81 + ioctl(fd,BLKFRASET,fahead);
1.82 DEBUG("set_param: readahead=%ld freadahead=%ld\n",ahead,fahead);
1.83 #else
1.84 - fprintf("Can't set readahead parameter. Ioctl's not available\n");
1.85 + fprintf(stderr,"Can't set readahead parameter. Ioctl's not available\n");
1.86 #endif
1.87 }
1.88
1.89 /****************************************************************************/
1.90
1.91 -int full_read(int fd, void *buf, int count)
1.92 +int getCdHeader(struct cd_header *cd)
1.93 {
1.94 - int total=0;
1.95 -
1.96 - while(count>0) {
1.97 - int bytes;
1.98 - bytes=read(fd,buf,count); if(bytes<0) return bytes;
1.99 - if(bytes==0) break;
1.100 - count-=bytes; total+=bytes; buf+=bytes;
1.101 - }
1.102 - return total;
1.103 -}
1.104 -
1.105 -/****************************************************************************/
1.106 -
1.107 -void free_toc()
1.108 -{
1.109 - if(toc) { free(toc); toc=0; }
1.110 -}
1.111 -
1.112 -/****************************************************************************/
1.113 -
1.114 -int read_toc(int cd_fd, int trackinfos)
1.115 -{
1.116 - int i;
1.117 struct cdrom_tochdr cd_header;
1.118 struct cdrom_tocentry cd_entry;
1.119 - int tracks,start_track;
1.120 -
1.121 - /* read table of contents header */
1.122 - if(ioctl(cd_fd,CDROMREADTOCHDR,&cd_header)) {
1.123 - if(verbose) fprintf(stderr,"%s: Unable to read CD header, assuming empty CD-R\n", prg_name);
1.124 - cd_used=0; cd_avail=(long long)cd_len*CD_FRAMESIZE; return 0;
1.125 + int tracks;
1.126 +
1.127 + if(ioctl(fd,CDROMREADTOCHDR,&cd_header)<0) {
1.128 + if(verbose) fprintf(stderr,"%s: Unable to read CD header, assuming empty CD-R\n",prg_name);
1.129 + cd->start_track=1; cd->end_track=0;
1.130 + cd->used=0;
1.131 + return 0;
1.132 }
1.133
1.134 - /* get start and end tracks */
1.135 - start_track = cd_header.cdth_trk0;
1.136 - tracks = cd_header.cdth_trk1-start_track+1;
1.137 - DEBUG("read_toc: starttrack=%d tracks=%d\n",start_track,tracks);
1.138 + cd->start_track=cd_header.cdth_trk0;
1.139 + cd->end_track =cd_header.cdth_trk1;
1.140 + tracks=cd->end_track-cd->start_track+1;
1.141
1.142 - free_toc();
1.143 - if(!(toc=calloc(tracks+1,sizeof(struct toc_entry)))) serror("No memory for TOC");
1.144 + cd_entry.cdte_format=CDROM_LBA;
1.145 + cd_entry.cdte_track=CDROM_LEADOUT;
1.146 + if(ioctl(fd,CDROMREADTOCENTRY,&cd_entry)<0) error("Ioctl failed (lead-out)");
1.147
1.148 - /* set some parameters */
1.149 - cd_entry.cdte_format=CDROM_LBA;
1.150 -
1.151 - /* read lead-out */
1.152 - cd_entry.cdte_track=CDROM_LEADOUT;
1.153 - if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading lead-out");
1.154 -
1.155 - toc[0].track_no=CDROM_LEADOUT; /* not a real track */
1.156 - toc[0].sec_start=cd_entry.cdte_addr.lba;
1.157 -
1.158 - cd_used =(long long)toc[0].sec_start*CD_FRAMESIZE;
1.159 - cd_avail =(long long)cd_len*CD_FRAMESIZE-cd_used;
1.160 - cd_avail-=(tracks>1?MIN_FREE_2:MIN_FREE_1);
1.161 - 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);
1.162 -
1.163 - if(cd_avail<0) cd_avail=0; /* can be <0 due to assumed additional lead-in/out */
1.164 -
1.165 - /* read rest of tracks */
1.166 - for(i=1; i<=tracks; i++) {
1.167 - cd_entry.cdte_track=start_track+i-1;
1.168 - if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading TOC");
1.169 -
1.170 - toc[i].track_no=start_track+i-1;
1.171 - toc[i].sec_start=cd_entry.cdte_addr.lba;
1.172 - if(cd_entry.cdte_ctrl&CDROM_DATA_TRACK) toc[i].is_data=1;
1.173 - }
1.174 -
1.175 - /* calculate end sectors */
1.176 - toc[tracks].sec_end = toc[ 0].sec_start - 1 - RUNOUT;
1.177 - for(i=1; i<tracks; i++)
1.178 - toc[i].sec_end = toc[i+1].sec_start - 1 - RUNOUT - (i>1?(MIN_FREE_2/CD_FRAMESIZE):(MIN_FREE_1/CD_FRAMESIZE));
1.179 -
1.180 - if(trackinfos)
1.181 - /* now loop through tracks and read header info */
1.182 - for(i=1; i<=tracks; i++) {
1.183 - char inbuffer[CD_FRAMESIZE];
1.184 - struct header_block *track_header=(struct header_block *)&inbuffer[0];
1.185 -
1.186 - if (toc[i].is_data == 1) {
1.187 - if(lseek64(cd_fd,(long long)toc[i].sec_start*CD_FRAMESIZE,SEEK_SET)<0) error("Seek failed");
1.188 -
1.189 - if(full_read(cd_fd,inbuffer,CD_FRAMESIZE)==CD_FRAMESIZE) {
1.190 - if(!strncmp(SHORT_HDR,track_header->id_str,strlen(SHORT_HDR))) {
1.191 - toc[i].is_cdbackup=1;
1.192 - strncpy(toc[i].id_str,track_header->id_str,32); toc[i].id_str[32]=0;
1.193 - strncpy(toc[i].vol_id, track_header->vol_id,32); toc[i].vol_id[32]=0;
1.194 - strncpy(toc[i].t_stamp, track_header->t_stamp,12); toc[i].t_stamp[12]=0;
1.195 - toc[i].disk_set = track_header->disk_set;
1.196 - }
1.197 - }
1.198 - }
1.199 - }
1.200 -
1.201 + cd->used=cd_entry.cdte_addr.lba + (tracks==1 ? LEADOUT_1:LEADOUT_2);
1.202 return tracks;
1.203 }
1.204
1.205 /****************************************************************************/
1.206
1.207 -void print_space()
1.208 +void getCdTrack(int num, struct cd_track *cd)
1.209 {
1.210 - if(verbose)
1.211 - fprintf(stderr,
1.212 - "Disk size: %7lld kB (%7ld blocks)\n"
1.213 - "Space used: %7lld kB (%7lld blocks)\n"
1.214 - "Space avail:%7lld kB (%7lld blocks)\n",
1.215 - (long long)cd_len*CD_FRAMESIZE/1024,cd_len,
1.216 - cd_used/1024, cd_used/CD_FRAMESIZE,
1.217 - cd_avail/1024, cd_avail/CD_FRAMESIZE);
1.218 + struct cdrom_tocentry cd_entry;
1.219 +
1.220 + cd_entry.cdte_format=CDROM_LBA;
1.221 + cd_entry.cdte_track=num;
1.222 + if(ioctl(fd,CDROMREADTOCENTRY,&cd_entry)<0) error("Ioctl failed (toc entry)");
1.223 +
1.224 + cd->start_sec =cd_entry.cdte_addr.lba;
1.225 + cd->leadout_size=RUNOUT+(num==cd->start_track ? LEADOUT_1:LEADOUT_2);
1.226 + cd->is_data =(cd_entry.cdte_ctrl&CDROM_DATA_TRACK) ? 1:0;
1.227 }