int CDRipMain::stop_loop() { if(interactive) { progress->stop_progress(); delete progress; } delete buffer; close_drive(); return 0; }
int main(int argc, char *argv[]) { int c; char *dev_id=NULL, *fmt_id=NULL, *output=NULL; extern char *optarg; extern int optind; struct format_info *format; struct phys *phys; FILE *f; int track, side; int must_close_output=0; my_name=argv[0]; while((c=getopt(argc,argv,"d:f:"))!=-1) { switch(c) { case 'd': dev_id=optarg; break; case 'f': fmt_id=optarg; break; case '?': return usage(); } } if(!fmt_id) { fprintf(stderr,"%s: Missing -f option.\n",my_name); return usage(); } format=format_by_id(fmt_id); if(!format) { fprintf(stderr,"%s: Invalid format '%s'\n",my_name,fmt_id); return usage(); } phys=format->phys; if(optind<argc) { output=argv[optind]; optind++; } else { fprintf(stderr,"%s: Missing destination filename.\n",my_name); return usage(); } if(optind<argc) { fprintf(stderr,"%s: Too many arguments.\n",my_name); return usage(); } if(!get_drive_list()) { fprintf(stderr,"%s: No devices found.\n",my_name); return 1; } if(dev_id) { if(open_drive_by_id(dev_id)!=0) { fprintf(stderr,"%s: Unable to open device '%s'.\n",my_name,dev_id); return 1; } } else { dev_id=open_default_drive(); if(!dev_id) { fprintf(stderr,"%s: Unable to open default device.\n",my_name); return 1; } } if(strcmp(output,"-")==0) { f=stdout; output="standard output"; #ifdef WIN32 if(_setmode(_fileno(stdout),_O_BINARY)==-1) { perror("_setmode"); fprintf(stderr,"%s: Unable to set stdout to binary mode.\n",my_name); close_drive(); return 1; } #endif } else { f=fopen(output,"wb"); must_close_output=1; } if(!f) { if(must_close_output) perror("fopen"); fprintf(stderr,"%s: Unable to open destination file.\n",my_name); close_drive(); return 1; } fprintf(stderr,"Imaging %s disk in %s to %s...\n",format->desc,dev_id,output); if(fc_recalibrate()!=0) { fprintf(stderr,"%s: Unable to recalibrate drive.\n",my_name); if(must_close_output) fclose(f); close_drive(); return 1; } if(fc_set_density(phys->density(phys))!=0) { fprintf(stderr,"%s: Unable to set density.\n",my_name); if(must_close_output) fclose(f); close_drive(); return 1; } if(phys->prepare(phys)!=0) { fprintf(stderr,"%s: Unable to begin reading disk.\n",my_name); if(must_close_output) fclose(f); close_drive(); return 1; } for(track=phys->min_track(phys);track<=phys->max_track(phys);track++) { for(side=phys->min_side(phys);side<=phys->max_side(phys);side++) { if(image_track(f,phys,track,side)!=0) { if(must_close_output) fclose(f); close_drive(); return 1; } } } if(fflush(f)!=0) { perror("fflush"); if(must_close_output) fclose(f); fprintf(stderr,"Unable to write to destination file!\n"); close_drive(); return 1; } if(must_close_output && fclose(f)!=0) { perror("fclose"); fprintf(stderr,"Unable to write to destination file!\n"); close_drive(); return 1; } close_drive(); if(errors) { fprintf(stderr,"\nSome sectors did not read correctly.\n"); return 1; } else { fprintf(stderr,"\nDone!\n"); return 0; } }
int CDRipMain::get_toc() { // test CD int result = 0, i, tracks; struct cdrom_tochdr hdr; struct cdrom_tocentry entry[100]; BC_DisplayInfo info; result = open_drive(); if(ioctl(cdrom, CDROMREADTOCHDR, &hdr) < 0) { close(cdrom); ErrorBox window(PROGRAM_NAME ": CD Ripper", info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(_("Can't get total from table of contents.")); window.run_window(); result = 1; } for(i = 0; i < hdr.cdth_trk1; i++) { entry[i].cdte_track = 1 + i; entry[i].cdte_format = CDROM_LBA; if(ioctl(cdrom, CDROMREADTOCENTRY, &entry[i]) < 0) { ioctl(cdrom, CDROMSTOP); close(cdrom); ErrorBox window(PROGRAM_NAME ": CD Ripper", info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(_("Can't get table of contents entry.")); window.run_window(); result = 1; break; } } entry[i].cdte_track = CDROM_LEADOUT; entry[i].cdte_format = CDROM_LBA; if(ioctl(cdrom, CDROMREADTOCENTRY, &entry[i]) < 0) { ioctl(cdrom, CDROMSTOP); close(cdrom); ErrorBox window(PROGRAM_NAME ": CD Ripper", info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(_("Can't get table of contents leadout.")); window.run_window(); result = 1; } tracks = hdr.cdth_trk1+1; if(track1 <= 0 || track1 > tracks) { ioctl(cdrom, CDROMSTOP); close(cdrom); ErrorBox window(PROGRAM_NAME ": CD Ripper", info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(_("Start track is out of range.")); window.run_window(); result = 1; } // Clamp to highest track if(track2 > tracks) { track2 = tracks; } if(track2 < track1 || track2 <= 0) { ioctl(cdrom, CDROMSTOP); close(cdrom); ErrorBox window(PROGRAM_NAME ": CD Ripper", info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(_("End track is out of range.")); window.run_window(); result = 1; } if(track1 == track2 && min2 == 0 && sec2 == 0) { ioctl(cdrom, CDROMSTOP); close(cdrom); ErrorBox window(PROGRAM_NAME ": CD Ripper", info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(_("End position is out of range.")); window.run_window(); result = 1; } startlba = endlba = 0; if(!result) { startlba = entry[track1 - 1].cdte_addr.lba; startlba += (min1 * 44100 * 4 * 60 + sec1 * 44100 * 4) / FRAMESIZE; endlba = entry[track2 - 1].cdte_addr.lba; if(track2 < tracks) { endlba += (min2 * 44100 * 4 * 60 + sec2 * 44100 * 4) / FRAMESIZE; } } //printf("CDRipMain::get_toc %ld %ld\n", startlba, endlba); close_drive(); return result; }
void vinum_daemon(void) { int s; struct daemonq *request; curproc->p_flag |= P_INMEM | P_SYSTEM; /* we're a system process */ daemon_save_config(); /* start by saving the configuration */ daemonpid = curproc->p_pid; /* mark our territory */ while (1) { tsleep(&vinum_daemon, PRIBIO, "vinum", 0); /* wait for something to happen */ /* * It's conceivable that, as the result of an * I/O error, we'll be out of action long * enough that another daemon gets started. * That's OK, just give up gracefully. */ if (curproc->p_pid != daemonpid) { /* we've been ousted in our sleep */ if (daemon_options & daemon_verbose) log(LOG_INFO, "vinum: abdicating\n"); return; } while (daemonq != NULL) { /* we have work to do, */ s = splhigh(); /* don't get interrupted here */ request = daemonq; /* get the request */ daemonq = daemonq->next; /* and detach it */ if (daemonq == NULL) /* got to the end, */ dqend = NULL; /* no end any more */ splx(s); switch (request->type) { /* * We had an I/O error on a request. Go through the * request and try to salvage it */ case daemonrq_ioerror: if (daemon_options & daemon_verbose) { struct request *rq = request->info.rq; log(LOG_WARNING, "vinum: recovering I/O request: %p\n%s dev %d.%d, offset 0x%x, length %ld\n", rq, rq->bp->b_flags & B_READ ? "Read" : "Write", major(rq->bp->b_dev), minor(rq->bp->b_dev), rq->bp->b_blkno, rq->bp->b_bcount); } recover_io(request->info.rq); /* the failed request */ break; /* * Write the config to disk. We could end up with * quite a few of these in a row. Only honour the * last one */ case daemonrq_saveconfig: if ((daemonq == NULL) /* no more requests */ ||(daemonq->type != daemonrq_saveconfig)) { /* or the next isn't the same */ if (((daemon_options & daemon_noupdate) == 0) /* we're allowed to do it */ &&((vinum_conf.flags & VF_READING_CONFIG) == 0)) { /* and we're not building the config now */ /* * We obviously don't want to save a * partial configuration. Less obviously, * we don't need to do anything if we're * asked to write the config when we're * building it up, because we save it at * the end. */ if (daemon_options & daemon_verbose) log(LOG_INFO, "vinum: saving config\n"); daemon_save_config(); /* save it */ } } break; case daemonrq_return: /* been told to stop */ if (daemon_options & daemon_verbose) log(LOG_INFO, "vinum: stopping\n"); daemon_options |= daemon_stopped; /* note that we've stopped */ Free(request); while (daemonq != NULL) { /* backed up requests, */ request = daemonq; /* get the request */ daemonq = daemonq->next; /* and detach it */ Free(request); /* then free it */ } wakeup(&vinumclose); /* and wake any waiting vinum(8)s */ return; case daemonrq_ping: /* tell the caller we're here */ if (daemon_options & daemon_verbose) log(LOG_INFO, "vinum: ping reply\n"); wakeup(&vinum_finddaemon); /* wake up the caller */ break; case daemonrq_closedrive: /* close a drive */ close_drive(request->info.drive); /* do it */ break; case daemonrq_init: /* initialize a plex */ /* XXX */ case daemonrq_revive: /* revive a subdisk */ /* XXX */ /* FALLTHROUGH */ default: log(LOG_WARNING, "Invalid request\n"); break; } if (request->privateinuse) /* one of ours, */ request->privateinuse = 0; /* no longer in use */ else Free(request); /* return it */ } } }