1.1 --- a/misc.c Sat Dec 29 15:23:55 2007 +0100
1.2 +++ b/misc.c Sat Dec 29 15:25:21 2007 +0100
1.3 @@ -1,5 +1,5 @@
1.4 /* misc.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 @@ -30,6 +30,9 @@
1.11 #include <sys/wait.h>
1.12 #include <errno.h>
1.13
1.14 +#include "cdrom.h"
1.15 +#include "debug.h"
1.16 +
1.17 extern char *prg_name;
1.18
1.19 /****************************************************************************/
1.20 @@ -50,34 +53,156 @@
1.21
1.22 /****************************************************************************/
1.23
1.24 -int start_diskchange(char *multicmd, char *cd_dev)
1.25 -{
1.26 -int pid, status=0;
1.27 -char buffer[12];
1.28 -
1.29 -if(multicmd) { /* we have an external script */
1.30 - if((pid=fork())<0) error("Fork failed in diskchange");
1.31 - if(pid==0) { /* child */
1.32 - char *argv[3];
1.33 -
1.34 - dup2(2,0); dup2(2,1); /* duplicate stderr as stdin/stdout */
1.35 - argv[0] = multicmd;
1.36 - argv[1] = cd_dev;
1.37 - argv[2] = 0;
1.38 - execvp(multicmd, argv);
1.39 - error("Starting diskchange command failed");
1.40 - }
1.41 -
1.42 - while(1) {
1.43 - if(waitpid(pid,&status,0)==-1) { if (errno != EINTR) { status=-1; break; } }
1.44 - else break;
1.45 - }
1.46 - }
1.47 -else { /* use internal diskchange */
1.48 - fprintf(stderr,"\n\nPlease insert next disk and press RETURN\n\n\n");
1.49 - do {
1.50 - pid=read(2,buffer,sizeof(buffer));
1.51 - } while(pid==sizeof(buffer) && buffer[sizeof(buffer)-1]!='\n');
1.52 - }
1.53 -return status;
1.54 -}
1.55 +long long FlexLen(char *optarg)
1.56 +{
1.57 + char *end;
1.58 + long long len;
1.59 + errno=0; len=strtoll(optarg,&end,10);
1.60 + if(errno==ERANGE || len<1) serror("Option -l: length out of range (must be >=1)\n");
1.61 + switch(*end) {
1.62 + case 'K': /* kilo-bytes*/
1.63 + case 'k':
1.64 + len*=1024; break;
1.65 + case 0: /* mega-bytes */
1.66 + case 'M':
1.67 + case 'm':
1.68 + len*=(1024*1024); break;
1.69 + case 'G':
1.70 + case 'g':
1.71 + len*=(1024*1024*1024LL); break;
1.72 + case 's':
1.73 + case 'S':
1.74 + len*=CD_FRAMESIZE; break;
1.75 + default:
1.76 + serror("Unknown extention for media size");
1.77 + }
1.78 + DEBUG("media size len=%lld blocks=%lld\n",len,len/CD_FRAMESIZE);
1.79 + return len;
1.80 +}
1.81 +
1.82 +/****************************************************************************/
1.83 +
1.84 +char *FlexSize(char *buff, long long val)
1.85 +{
1.86 + char *unit=" ";
1.87 + if(val > 1024*1024*1024*16LL) { val/=1024*1024*1024LL; unit="G"; }
1.88 + else if(val > 1024*1024*16LL) { val/=1024*1024LL; unit="M"; }
1.89 + else if(val > 1024*16LL) { val/=1024LL; unit="k"; }
1.90 + sprintf(buff,"%5lld %sB",val,unit);
1.91 + return buff;
1.92 +}
1.93 +
1.94 +/****************************************************************************/
1.95 +
1.96 +int full_read(int fd, void *buf, int count)
1.97 +{
1.98 + int total=0;
1.99 + while(count>0) {
1.100 + int bytes;
1.101 + bytes=read(fd,buf,count);
1.102 + if(bytes==0) break;
1.103 + else if(bytes<0) {
1.104 + if(errno!=EAGAIN) error("Read failed");
1.105 + usleep(200*1000);
1.106 + }
1.107 + else {
1.108 + count-=bytes; buf+=bytes; total+=bytes;
1.109 + }
1.110 + }
1.111 + return total;
1.112 +}
1.113 +
1.114 +/****************************************************************************/
1.115 +
1.116 +void diskchange(char *multicmd, char *cd_dev)
1.117 +{
1.118 + int pid, status=0;
1.119 + char buffer[12];
1.120 +
1.121 + if(multicmd) { /* we have an external script */
1.122 + DEBUG("external diskchange started '%s'\n",multicmd);
1.123 + if((pid=fork())<0) error("Fork failed (diskchange)");
1.124 + if(pid==0) { /* child */
1.125 + char *argv[3];
1.126 +
1.127 + dup2(2,0); dup2(2,1); /* duplicate stderr as stdin/stdout */
1.128 + argv[0] = multicmd;
1.129 + argv[1] = cd_dev;
1.130 + argv[2] = 0;
1.131 + execvp(multicmd, argv);
1.132 + error("Exec failed (diskchange)");
1.133 + }
1.134 +
1.135 + while(1) {
1.136 + if(waitpid(pid,&status,0)==-1) { if (errno!=EINTR) { status=-1; break; } }
1.137 + else break;
1.138 + }
1.139 + }
1.140 + else { /* use internal diskchange */
1.141 + DEBUG("internal diskchange started\n");
1.142 + fprintf(stderr,"\n\nPlease insert next disk and press RETURN\n\n\n");
1.143 + do {
1.144 + pid=read(2,buffer,sizeof(buffer));
1.145 + if(pid<0 && errno!=EAGAIN) error("Read failed (diskchange)");
1.146 + } while(pid<=0 || (pid==sizeof(buffer) && buffer[sizeof(buffer)-1]!='\n'));
1.147 + }
1.148 + if(status) serror("Diskchange command failed");
1.149 + DEBUG("diskchange completed\n");
1.150 +}
1.151 +
1.152 +/****************************************************************************/
1.153 +
1.154 +static unsigned long crc_table[256] = {
1.155 + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
1.156 + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1.157 + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
1.158 + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1.159 + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
1.160 + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1.161 + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
1.162 + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1.163 + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
1.164 + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1.165 + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
1.166 + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1.167 + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
1.168 + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1.169 + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
1.170 + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1.171 + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
1.172 + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1.173 + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
1.174 + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1.175 + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
1.176 + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1.177 + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
1.178 + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1.179 + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
1.180 + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1.181 + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
1.182 + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1.183 + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
1.184 + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1.185 + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
1.186 + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1.187 + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
1.188 + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1.189 + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
1.190 + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1.191 + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
1.192 + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1.193 + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
1.194 + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1.195 + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
1.196 + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1.197 + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1.198 + };
1.199 +
1.200 +unsigned long crc32(char *data, int len)
1.201 +{
1.202 + unsigned long crc=0xffffffff;
1.203 + int i;
1.204 + for(i=0 ; i<len ; i++)
1.205 + crc=(crc<<8) ^ crc_table[((crc>>24)^*data++)&0xff];
1.206 + return crc;
1.207 +}