misc.c
branchtrunk
changeset 4 79da91042fcc
parent 0 d85c12073dea
child 15 a9348bf5f6e7
equal deleted inserted replaced
3:d09ec85ffdfe 4:79da91042fcc
     1 /* misc.c
     1 /* misc.c
     2 Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
     2 Copyright (c) 2000-2004 Craig Condit, Stefan Hülswitt.
     3 
     3 
     4 Redistribution and use in source and binary forms, with or without
     4 Redistribution and use in source and binary forms, with or without
     5 modification, are permitted provided that the following conditions are met: 
     5 modification, are permitted provided that the following conditions are met: 
     6 
     6 
     7 1. Redistributions of source code must retain the above copyright notice,
     7 1. Redistributions of source code must retain the above copyright notice,
    28 #include <unistd.h>
    28 #include <unistd.h>
    29 #include <string.h>
    29 #include <string.h>
    30 #include <sys/wait.h>
    30 #include <sys/wait.h>
    31 #include <errno.h>
    31 #include <errno.h>
    32 
    32 
       
    33 #include "cdrom.h"
       
    34 #include "debug.h"
       
    35 
    33 extern char *prg_name;
    36 extern char *prg_name;
    34 
    37 
    35 /****************************************************************************/
    38 /****************************************************************************/
    36 
    39 
    37 void error(char *text)
    40 void error(char *text)
    48   exit(1);
    51   exit(1);
    49 }
    52 }
    50 
    53 
    51 /****************************************************************************/
    54 /****************************************************************************/
    52 
    55 
    53 int start_diskchange(char *multicmd, char *cd_dev)
    56 long long FlexLen(char *optarg)
    54 {
    57 {
    55 int pid, status=0;
    58   char *end;
    56 char buffer[12];
    59   long long len;
    57 
    60   errno=0; len=strtoll(optarg,&end,10);
    58 if(multicmd) { /* we have an external script */
    61   if(errno==ERANGE || len<1) serror("Option -l: length out of range (must be >=1)\n");
    59   if((pid=fork())<0) error("Fork failed in diskchange");
    62   switch(*end) {
    60   if(pid==0) { /* child */
    63     case 'K': /* kilo-bytes*/
    61     char *argv[3];
    64     case 'k':
    62 
    65       len*=1024; break;
    63     dup2(2,0); dup2(2,1); /* duplicate stderr as stdin/stdout */
    66     case 0:   /* mega-bytes */
    64     argv[0] = multicmd;
    67     case 'M':
    65     argv[1] = cd_dev;
    68     case 'm':
    66     argv[2] = 0;
    69       len*=(1024*1024); break;
    67     execvp(multicmd, argv);
    70     case 'G':
    68     error("Starting diskchange command failed");
    71     case 'g':
    69     }
    72       len*=(1024*1024*1024LL); break;
    70 
    73     case 's':
    71   while(1) {
    74     case 'S':
    72     if(waitpid(pid,&status,0)==-1) { if (errno != EINTR) { status=-1; break; } }
    75       len*=CD_FRAMESIZE; break;
    73     else break;
    76     default:
    74     }
    77       serror("Unknown extention for media size");
    75   }
    78     }
    76 else { /* use internal diskchange */
    79   DEBUG("media size len=%lld blocks=%lld\n",len,len/CD_FRAMESIZE);
    77   fprintf(stderr,"\n\nPlease insert next disk and press RETURN\n\n\n");
    80   return len;
    78   do {
    81 }
    79     pid=read(2,buffer,sizeof(buffer));
    82 
    80     } while(pid==sizeof(buffer) && buffer[sizeof(buffer)-1]!='\n');
    83 /****************************************************************************/
    81   }
    84 
    82 return status;
    85 char *FlexSize(char *buff, long long val)
    83 }
    86 {
       
    87   char *unit=" ";
       
    88        if(val > 1024*1024*1024*16LL) { val/=1024*1024*1024LL; unit="G"; }
       
    89   else if(val > 1024*1024*16LL)      { val/=1024*1024LL; unit="M"; }
       
    90   else if(val > 1024*16LL)           { val/=1024LL; unit="k"; }
       
    91   sprintf(buff,"%5lld %sB",val,unit);
       
    92   return buff;
       
    93 }
       
    94 
       
    95 /****************************************************************************/
       
    96 
       
    97 int full_read(int fd, void *buf, int count)
       
    98 {
       
    99   int total=0;
       
   100   while(count>0) {
       
   101     int bytes;
       
   102     bytes=read(fd,buf,count);
       
   103     if(bytes==0) break;
       
   104     else if(bytes<0) {
       
   105       if(errno!=EAGAIN) error("Read failed");
       
   106       usleep(200*1000);
       
   107       }
       
   108     else {
       
   109       count-=bytes; buf+=bytes; total+=bytes;
       
   110       }
       
   111     }
       
   112   return total;
       
   113 }
       
   114 
       
   115 /****************************************************************************/
       
   116 
       
   117 void diskchange(char *multicmd, char *cd_dev)
       
   118 {
       
   119   int pid, status=0;
       
   120   char buffer[12];
       
   121 
       
   122   if(multicmd) { /* we have an external script */
       
   123     DEBUG("external diskchange started '%s'\n",multicmd);
       
   124     if((pid=fork())<0) error("Fork failed (diskchange)");
       
   125     if(pid==0) { /* child */
       
   126       char *argv[3];
       
   127 
       
   128       dup2(2,0); dup2(2,1); /* duplicate stderr as stdin/stdout */
       
   129       argv[0] = multicmd;
       
   130       argv[1] = cd_dev;
       
   131       argv[2] = 0;
       
   132       execvp(multicmd, argv);
       
   133       error("Exec failed (diskchange)");
       
   134       }
       
   135 
       
   136     while(1) {
       
   137       if(waitpid(pid,&status,0)==-1) { if (errno!=EINTR) { status=-1; break; } }
       
   138       else break;
       
   139       }
       
   140     }
       
   141   else { /* use internal diskchange */
       
   142     DEBUG("internal diskchange started\n");
       
   143     fprintf(stderr,"\n\nPlease insert next disk and press RETURN\n\n\n");
       
   144     do {
       
   145       pid=read(2,buffer,sizeof(buffer));
       
   146       if(pid<0 && errno!=EAGAIN) error("Read failed (diskchange)");
       
   147       } while(pid<=0 || (pid==sizeof(buffer) && buffer[sizeof(buffer)-1]!='\n'));
       
   148     }
       
   149   if(status) serror("Diskchange command failed");
       
   150   DEBUG("diskchange completed\n");
       
   151 }
       
   152 
       
   153 /****************************************************************************/
       
   154 
       
   155 static unsigned long crc_table[256] = {
       
   156   0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
       
   157   0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
       
   158   0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
       
   159   0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
       
   160   0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
       
   161   0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
       
   162   0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
       
   163   0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
       
   164   0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
       
   165   0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
       
   166   0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
       
   167   0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
       
   168   0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
       
   169   0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
       
   170   0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
       
   171   0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
       
   172   0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
       
   173   0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
       
   174   0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
       
   175   0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
       
   176   0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
       
   177   0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
       
   178   0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
       
   179   0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
       
   180   0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
       
   181   0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
       
   182   0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
       
   183   0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
       
   184   0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
       
   185   0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
       
   186   0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
       
   187   0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
       
   188   0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
       
   189   0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
       
   190   0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
       
   191   0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
       
   192   0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
       
   193   0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
       
   194   0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
       
   195   0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
       
   196   0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
       
   197   0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
       
   198   0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
       
   199   };
       
   200 
       
   201 unsigned long crc32(char *data, int len)
       
   202 {
       
   203   unsigned long crc=0xffffffff;
       
   204   int i;
       
   205   for(i=0 ; i<len ; i++)
       
   206     crc=(crc<<8) ^ crc_table[((crc>>24)^*data++)&0xff];
       
   207   return crc;
       
   208 }