#include <libburn/libburn.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
Include dependency graph for libburner.c:
Go to the source code of this file.
Defines | |
#define | _LARGEFILE_SOURCE 1 |
Overview. | |
#define | _FILE_OFFSET_BITS 64 |
Functions | |
int | libburner_aquire_by_adr (char *drive_adr) |
If the persistent drive address is known, then this approach is much more un-obtrusive to the systemwide livestock of drives. | |
int | libburner_aquire_by_driveno (int *driveno) |
This method demonstrates how to use libburn without knowing a persistent drive address in advance. | |
int | libburner_aquire_drive (char *drive_adr, int *driveno) |
You need to aquire a drive before burning. | |
int | libburner_blank_disc (struct burn_drive *drive, int blank_fast) |
Makes a previously used CD-RW ready for thorough re-usal. | |
int | libburner_regrab (struct burn_drive *drive) |
This gesture is necessary to get the drive info after blanking. | |
int | libburner_payload (struct burn_drive *drive, const char *source_adr, off_t size) |
Brings the preformatted image (ISO 9660, afio, ext2, whatever) onto media. | |
int | libburner_setup (int argc, char **argv, char drive_adr[], int *driveno, int *do_blank, char source_adr[], off_t *size) |
Converts command line arguments into a few program parameters. | |
int | main (int argc, char **argv) |
Variables | |
static struct burn_drive_info * | drive_list |
This list will hold the drives known to libburn. | |
static unsigned int | drive_count |
If you start a long lasting operation with drive_count > 1 then you are not friendly to the users of other drives on those systems. | |
static int | drive_is_grabbed = 0 |
This variable indicates wether the drive is grabbed and must be finally released. | |
static int | simulate_burn = 0 |
Here you may enable simulated burn by default. |
#define _FILE_OFFSET_BITS 64 |
Definition at line 42 of file libburner.c.
#define _LARGEFILE_SOURCE 1 |
Overview.
libburner is a minimal demo application for the library libburn as provided on http://libburn.pykix.org . It can list the available devices, can blank a CD-RW and can burn to CD-R or CD-RW. It's main purpose, nevertheless, is to show you how to use libburn and also to serve the libburn team as reference application. libburner.c does indeed define the standard way how above three gestures can be implemented and stay upward compatible for a good while.
Before you can do anything, you have to initialize libburn by burn_initialize() as it is done in main() at the end of this file. Then you aquire a drive in an appropriate way conforming to the API. The two main approaches are shown here in application functions: libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions libburner_aquire_by_driveno() demonstrates a scan-and-choose approach With that aquired drive you can blank a CD-RW libburner_blank_disc() Between blanking and burning one eventually has to reload the drive status libburner_regrab() With the aquired drive you can burn to CD-R or blank CD-RW libburner_payload() When everything is done, main() releases the drive and shuts down libburn: burn_drive_release(); burn_finish()
Definition at line 39 of file libburner.c.
int libburner_aquire_by_adr | ( | char * | drive_adr | ) |
If the persistent drive address is known, then this approach is much more un-obtrusive to the systemwide livestock of drives.
Only the given drive device will be opened during this procedure.
Definition at line 119 of file libburner.c.
References burn_drive_scan_and_grab(), drive_is_grabbed, and drive_list.
Referenced by libburner_aquire_drive().
00120 { 00121 int ret; 00122 00123 printf("Aquiring drive '%s' ...\n",drive_adr); 00124 ret = burn_drive_scan_and_grab(&drive_list,drive_adr,1); 00125 if (ret <= 0) { 00126 fprintf(stderr,"FAILURE with persistent drive address '%s'\n", 00127 drive_adr); 00128 if (strncmp(drive_adr,"/dev/sg",7) != 0 && 00129 strncmp(drive_adr,"/dev/hd",7) != 0) 00130 fprintf(stderr,"\nHINT: Consider addresses like '/dev/hdc' or '/dev/sg0'\n"); 00131 } else { 00132 printf("Done\n"); 00133 drive_is_grabbed = 1; 00134 } 00135 return ret; 00136 }
int libburner_aquire_by_driveno | ( | int * | driveno | ) |
This method demonstrates how to use libburn without knowing a persistent drive address in advance.
It has to make sure that after assessing the list of available drives, all unwanted drives get closed again. As long as they are open, no other libburn instance can see them. This is an intended locking feature. The application is responsible for giving up the locks by either burn_drive_release() (only after burn_drive_grab() !), burn_drive_info_forget(), burn_drive_info_free(), or burn_finish().
driveno | the index number in libburn's drive list. This will get set to 0 on success and will then be the drive index to use in the further dourse of processing. |
Definition at line 151 of file libburner.c.
References BURN_DRIVE_ADR_LEN, burn_drive_get_adr(), burn_drive_grab(), burn_drive_info_forget(), burn_drive_scan(), burn_drive_info::drive, drive_count, drive_is_grabbed, drive_list, burn_drive_info::product, and burn_drive_info::vendor.
Referenced by libburner_aquire_drive().
00152 { 00153 char adr[BURN_DRIVE_ADR_LEN]; 00154 int ret, i; 00155 00156 printf("Beginning to scan for devices ...\n"); 00157 while (!burn_drive_scan(&drive_list, &drive_count)) 00158 usleep(1002); 00159 if (drive_count <= 0 && *driveno >= 0) { 00160 printf("FAILED (no drives found)\n"); 00161 return 0; 00162 } 00163 printf("Done\n"); 00164 00165 /* 00166 Interactive programs may choose the drive number at this moment. 00167 00168 drive[0] to drive[drive_count-1] are struct burn_drive_info 00169 as defined in libburn/libburn.h . This structure is part of API 00170 and thus will strive for future compatibility on source level. 00171 Have a look at the info offered. 00172 Caution: do not take .location for drive address. Always use 00173 burn_drive_get_adr() or you might become incompatible 00174 in future. 00175 Note: bugs with struct burn_drive_info - if any - will not be 00176 easy to fix. Please report them but also strive for 00177 workarounds on application level. 00178 */ 00179 printf("\nOverview of accessible drives (%d found) :\n", 00180 drive_count); 00181 printf("-----------------------------------------------------------------------------\n"); 00182 for (i = 0; i < drive_count; i++) { 00183 if (burn_drive_get_adr(&(drive_list[i]), adr) <=0) 00184 strcpy(adr, "-get_adr_failed-"); 00185 printf("%d --drive '%s' : '%s' '%s'\n", 00186 i,adr,drive_list[i].vendor,drive_list[i].product); 00187 } 00188 printf("-----------------------------------------------------------------------------\n\n"); 00189 00190 00191 /* 00192 On multi-drive systems save yourself from sysadmins' revenge. 00193 00194 Be aware that you hold reserved all available drives at this point. 00195 So either make your choice quick enough not to annoy other system 00196 users, or set free the drives for a while. 00197 00198 The tested way of setting free all drives is to shutdown the library 00199 and to restart when the choice has been made. The list of selectable 00200 drives should also hold persistent drive addresses as obtained 00201 above by burn_drive_get_adr(). By such an address one may use 00202 burn_drive_scan_and_grab() to finally aquire exactly one drive. 00203 00204 A not yet tested shortcut should be to call burn_drive_info_free() 00205 and to call either burn_drive_scan() or burn_drive_scan_and_grab() 00206 before accessing any drives again. 00207 00208 In both cases you have to be aware that the desired drive might get 00209 aquired in the meantime by another user resp. libburn process. 00210 */ 00211 00212 /* We already made our choice via command line. (default is 0) 00213 So we just have to keep our desired drive and drop all others. 00214 No other libburn instance will have a chance to steal our drive. 00215 */ 00216 if (*driveno < 0) { 00217 printf("Pseudo-drive \"-\" given : bus scanning done.\n"); 00218 return 2; /* the program will end after this */ 00219 } 00220 if (drive_count <= *driveno) { 00221 fprintf(stderr, 00222 "Found only %d drives. Number %d not available.\n", 00223 drive_count, *driveno); 00224 return 0; /* the program will end after this */ 00225 } 00226 00227 /* Drop all drives which we do not want to use */ 00228 for (i = 0; i < drive_count; i++) { 00229 if (i == *driveno) /* the one drive we want to keep */ 00230 continue; 00231 ret = burn_drive_info_forget(&(drive_list[i]),0); 00232 if (ret != 1) 00233 fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n", 00234 i, ret); 00235 else 00236 printf("Dropped unwanted drive %d\n",i); 00237 } 00238 /* Make the one we want ready for blanking or burning */ 00239 ret= burn_drive_grab(drive_list[*driveno].drive, 1); 00240 if (ret != 1) 00241 return 0; 00242 drive_is_grabbed = 1; 00243 return 1; 00244 }
int libburner_aquire_drive | ( | char * | drive_adr, | |
int * | driveno | |||
) |
You need to aquire a drive before burning.
The API offers this as one compact call and alternatively as application controllable gestures of whitelisting, scanning for drives and finally grabbing one of them.
If you have a persistent address of the drive, then the compact call is to prefer because it only touches one drive. On modern Linux kernels, there should be no fatal disturbance of ongoing burns of other libburn instances with any of our approaches. We use open(O_EXCL) by default. On /dev/hdX it should cooperate with growisofs and some cdrecord variants. On /dev/sgN versus /dev/scdM expect it not to respect other programs.
Definition at line 103 of file libburner.c.
References libburner_aquire_by_adr(), and libburner_aquire_by_driveno().
Referenced by main().
00104 { 00105 int ret; 00106 00107 if(drive_adr != NULL && drive_adr[0] != 0) 00108 ret = libburner_aquire_by_adr(drive_adr); 00109 else 00110 ret = libburner_aquire_by_driveno(driveno); 00111 return ret; 00112 }
int libburner_blank_disc | ( | struct burn_drive * | drive, | |
int | blank_fast | |||
) |
Makes a previously used CD-RW ready for thorough re-usal.
To our knowledge it is hardly possible to abort an ongoing blank operation because after start it is entirely handled by the drive. So expect a blank run to survive the end of the blanking process and be patient for the usual timespan of a normal blank run. Only after that time has surely elapsed, only then you should start any rescue attempts with the drive. If necessary at all.
Definition at line 256 of file libburner.c.
References BURN_DISC_APPENDABLE, BURN_DISC_BLANK, BURN_DISC_EMPTY, burn_disc_erasable(), burn_disc_erase(), BURN_DISC_FULL, burn_disc_get_status(), BURN_DISC_UNREADY, burn_drive_get_status(), and burn_progress::sector.
Referenced by main().
00257 { 00258 enum burn_disc_status disc_state; 00259 struct burn_progress progress; 00260 00261 while (burn_drive_get_status(drive, NULL)) 00262 usleep(1001); 00263 00264 while ((disc_state = burn_disc_get_status(drive)) == BURN_DISC_UNREADY) 00265 usleep(1001); 00266 printf( 00267 "Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n", 00268 disc_state); 00269 if (disc_state == BURN_DISC_BLANK) { 00270 fprintf(stderr, 00271 "IDLE: Blank CD media detected. Will leave it untouched\n"); 00272 return 2; 00273 } else if (disc_state == BURN_DISC_FULL || 00274 disc_state == BURN_DISC_APPENDABLE) { 00275 ; /* this is what libburn is willing to blank */ 00276 } else if (disc_state == BURN_DISC_EMPTY) { 00277 fprintf(stderr,"FATAL: No media detected in drive\n"); 00278 return 0; 00279 } else { 00280 fprintf(stderr, 00281 "FATAL: Cannot recognize drive and media state\n"); 00282 return 0; 00283 } 00284 if(!burn_disc_erasable(drive)) { 00285 fprintf(stderr, 00286 "FATAL : Media is not of erasable type\n"); 00287 return 0; 00288 } 00289 printf( 00290 "Beginning to %s-blank CD media.\n", (blank_fast?"fast":"full")); 00291 printf( 00292 "Expect some garbage sector numbers and some zeros at first.\n"); 00293 burn_disc_erase(drive, blank_fast); 00294 while (burn_drive_get_status(drive, &progress)) { 00295 printf("Blanking sector %d\n", progress.sector); 00296 sleep(1); 00297 } 00298 printf("Done\n"); 00299 return 1; 00300 }
int libburner_payload | ( | struct burn_drive * | drive, | |
const char * | source_adr, | |||
off_t | size | |||
) |
Brings the preformatted image (ISO 9660, afio, ext2, whatever) onto media.
To make sure your image is fully readable on any Linux machine, this function adds 300 kB of padding to the track.
Without a signal handler it is quite dangerous to abort the process while this function is active. See cdrskin/cdrskin.c and its usage of cdrskin/cleanup.[ch] for an example of application provided abort handling. It must cope with 2 of 3 threads reporting for being handled.
Without signal handler have ready a command line cdrecord dev=... -reset with a dev= previously inquired by cdrecord [dev=ATA] -scanbus in order to get your drive out of shock state after raw abort. Thanks to Joerg Schilling for helping out unquestioned. :)
In general, libburn is less prone to system problems than cdrecord, i believe. But cdrecord had long years of time to complete itself. We are still practicing. Help us with that. :))
Definition at line 345 of file libburner.c.
References BURN_BLOCK_RAW96R, BURN_BLOCK_SAO, burn_disc_add_session(), BURN_DISC_APPENDABLE, BURN_DISC_BLANK, burn_disc_create(), BURN_DISC_EMPTY, burn_disc_erasable(), burn_disc_free(), BURN_DISC_FULL, burn_disc_get_status(), BURN_DISC_UNREADY, burn_disc_write(), burn_drive_get_status(), burn_drive_set_speed(), BURN_DRIVE_SPAWNING, burn_fd_source_new(), burn_file_source_new(), BURN_MODE1, BURN_POS_END, burn_session_add_track(), burn_session_create(), burn_session_free(), burn_source_free(), BURN_SOURCE_OK, burn_structure_print_disc(), burn_track_create(), burn_track_define_data(), burn_track_free(), burn_track_set_source(), burn_write_opts_free(), burn_write_opts_new(), burn_write_opts_set_perform_opc(), burn_write_opts_set_simulate(), burn_write_opts_set_underrun_proof(), burn_write_opts_set_write_type(), BURN_WRITE_RAW, BURN_WRITE_SAO, burn_progress::sector, burn_progress::sectors, and simulate_burn.
Referenced by main().
00347 { 00348 struct burn_source *data_src; 00349 struct burn_disc *target_disc; 00350 struct burn_session *session; 00351 struct burn_write_opts *burn_options; 00352 enum burn_disc_status disc_state; 00353 struct burn_track *track; 00354 struct burn_progress progress; 00355 time_t start_time; 00356 int last_sector = 0; 00357 00358 target_disc = burn_disc_create(); 00359 session = burn_session_create(); 00360 burn_disc_add_session(target_disc, session, BURN_POS_END); 00361 track = burn_track_create(); 00362 00363 /* a padding of 300 kB is helpful to avoid the read-ahead bug */ 00364 burn_track_define_data(track, 0, 300*1024, 1, BURN_MODE1); 00365 00366 if (source_adr[0] == '-' && source_adr[1] == 0) { 00367 data_src = burn_fd_source_new(0, -1, size); 00368 printf("Note: using standard input as source with %.f bytes\n", 00369 (double) size); 00370 } else 00371 data_src = burn_file_source_new(source_adr, NULL); 00372 if (data_src == NULL) { 00373 fprintf(stderr, 00374 "FATAL: Could not open data source '%s'.\n",source_adr); 00375 if(errno!=0) 00376 fprintf(stderr,"(Most recent system error: %s )\n", 00377 strerror(errno)); 00378 return 0; 00379 } 00380 00381 if (burn_track_set_source(track, data_src) != BURN_SOURCE_OK) { 00382 printf("FATAL: Cannot attach source object to track object\n"); 00383 return 0; 00384 } 00385 burn_session_add_track(session, track, BURN_POS_END); 00386 burn_source_free(data_src); 00387 00388 while (burn_drive_get_status(drive, NULL)) 00389 usleep(1001); 00390 00391 /* Evaluate drive and media */ 00392 while ((disc_state = burn_disc_get_status(drive)) == BURN_DISC_UNREADY) 00393 usleep(1001); 00394 if (disc_state != BURN_DISC_BLANK) { 00395 if (disc_state == BURN_DISC_FULL || 00396 disc_state == BURN_DISC_APPENDABLE) { 00397 fprintf(stderr, 00398 "FATAL: Media with data detected. Need blank media.\n"); 00399 if (burn_disc_erasable(drive)) 00400 fprintf(stderr, "HINT: Try --blank_fast\n\n"); 00401 } else if (disc_state == BURN_DISC_EMPTY) 00402 fprintf(stderr,"FATAL: No media detected in drive\n"); 00403 else 00404 fprintf(stderr, 00405 "FATAL: Cannot recognize drive and media state\n"); 00406 return 0; 00407 } 00408 00409 burn_options = burn_write_opts_new(drive); 00410 burn_write_opts_set_perform_opc(burn_options, 0); 00411 00412 #ifdef Libburner_raw_mode_which_i_do_not_likE 00413 /* This yields higher CD capacity but hampers my IDE controller 00414 with burning on one drive and reading on another simultaneously. 00415 My burner does not obey the order --try_to_simulate in this mode. 00416 */ 00417 burn_write_opts_set_write_type(burn_options, 00418 BURN_WRITE_RAW, BURN_BLOCK_RAW96R); 00419 #else 00420 00421 /* This is by what cdrskin competes with cdrecord -sao which 00422 i understand is the mode preferrably advised by Joerg Schilling */ 00423 burn_write_opts_set_write_type(burn_options, 00424 BURN_WRITE_SAO, BURN_BLOCK_SAO); 00425 00426 #endif 00427 if(simulate_burn) 00428 printf("\n*** Will TRY to SIMULATE burning ***\n\n"); 00429 burn_write_opts_set_simulate(burn_options, simulate_burn); 00430 burn_structure_print_disc(target_disc); 00431 burn_drive_set_speed(drive, 0, 0); 00432 burn_write_opts_set_underrun_proof(burn_options, 1); 00433 00434 printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n"); 00435 start_time = time(0); 00436 burn_disc_write(burn_options, target_disc); 00437 00438 burn_write_opts_free(burn_options); 00439 while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) 00440 usleep(1002); 00441 while (burn_drive_get_status(drive, &progress)) { 00442 if( progress.sectors <= 0 || progress.sector == last_sector) 00443 printf( 00444 "Thank you for being patient since %d seconds.\n", 00445 (int) (time(0) - start_time)); 00446 else 00447 printf("Burning sector %d of %d\n", 00448 progress.sector, progress.sectors); 00449 last_sector = progress.sector; 00450 sleep(1); 00451 } 00452 printf("\n"); 00453 burn_track_free(track); 00454 burn_session_free(session); 00455 burn_disc_free(target_disc); 00456 if(simulate_burn) 00457 printf("\n*** Did TRY to SIMULATE burning ***\n\n"); 00458 return 0; 00459 }
int libburner_regrab | ( | struct burn_drive * | drive | ) |
This gesture is necessary to get the drive info after blanking.
It opens a small gap for losing the drive to another libburn instance. We will work on closing this gap.
Definition at line 307 of file libburner.c.
References burn_drive_grab(), burn_drive_release(), and drive_is_grabbed.
Referenced by main().
00307 { 00308 int ret; 00309 00310 printf("Releasing and regrabbing drive ...\n"); 00311 if (drive_is_grabbed) 00312 burn_drive_release(drive, 0); 00313 drive_is_grabbed = 0; 00314 ret = burn_drive_grab(drive, 0); 00315 if (ret != 0) { 00316 drive_is_grabbed = 1; 00317 printf("Done\n"); 00318 } else 00319 printf("FAILED\n"); 00320 return !!ret; 00321 }
int libburner_setup | ( | int | argc, | |
char ** | argv, | |||
char | drive_adr[], | |||
int * | driveno, | |||
int * | do_blank, | |||
char | source_adr[], | |||
off_t * | size | |||
) |
Converts command line arguments into a few program parameters.
drive_adr[] must provide at least BURN_DRIVE_ADR_LEN bytes. source_adr[] must provide at least 4096 bytes.
Definition at line 466 of file libburner.c.
References BURN_DRIVE_ADR_LEN, burn_set_verbosity(), and simulate_burn.
Referenced by main().
00468 { 00469 int i, insuffient_parameters = 0; 00470 int print_help = 0; 00471 00472 drive_adr[0] = 0; 00473 *driveno = 0; 00474 *do_blank = 0; 00475 source_adr[0] = 0; 00476 *size = 650*1024*1024; 00477 00478 for (i = 1; i < argc; ++i) { 00479 if (!strcmp(argv[i], "--blank_fast")) { 00480 *do_blank = 1; 00481 00482 } else if (!strcmp(argv[i], "--blank_full")) { 00483 *do_blank = 2; 00484 00485 } else if (!strcmp(argv[i], "--burn_for_real")) { 00486 simulate_burn = 0; 00487 00488 } else if (!strcmp(argv[i], "--drive")) { 00489 ++i; 00490 if (i >= argc) { 00491 fprintf(stderr,"--drive requires an argument\n"); 00492 return 1; 00493 } else if (strcmp(argv[i], "-") == 0) { 00494 drive_adr[0] = 0; 00495 *driveno = -1; 00496 } else if (isdigit(argv[i][0])) { 00497 drive_adr[0] = 0; 00498 *driveno = atoi(argv[i]); 00499 } else { 00500 if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) { 00501 fprintf(stderr,"--drive address too long (max. %d)\n", 00502 BURN_DRIVE_ADR_LEN-1); 00503 return 2; 00504 } 00505 strcpy(drive_adr, argv[i]); 00506 } 00507 } else if (!strcmp(argv[i], "--stdin_size")) { 00508 ++i; 00509 if (i >= argc) { 00510 fprintf(stderr,"--stdin_size requires an argument\n"); 00511 return 3; 00512 } else 00513 *size = atoi(argv[i]); 00514 if (*size < 600*1024) /* seems to be minimum readable track size */ 00515 *size = 600*1024; 00516 } else if (!strcmp(argv[i], "--try_to_simulate")) { 00517 simulate_burn = 1; 00518 00519 } else if (!strcmp(argv[i], "--verbose")) { 00520 ++i; 00521 if (i >= argc) { 00522 fprintf(stderr,"--verbose requires an argument\n"); 00523 return 4; 00524 } else 00525 burn_set_verbosity(atoi(argv[i])); 00526 } else if (!strcmp(argv[i], "--help")) { 00527 print_help = 1; 00528 00529 } else { 00530 if(strlen(argv[i]) >= 4096) { 00531 fprintf(stderr, "Source address too long (max. %d)\n", 4096-1); 00532 return 5; 00533 } 00534 strcpy(source_adr, argv[i]); 00535 } 00536 } 00537 insuffient_parameters = 1; 00538 if (*driveno < 0) 00539 insuffient_parameters = 0; 00540 if (source_adr[0] != 0) 00541 insuffient_parameters = 0; 00542 if (*do_blank) 00543 insuffient_parameters = 0; 00544 if (print_help || insuffient_parameters ) { 00545 printf("Usage: %s\n", argv[0]); 00546 printf(" [--drive <address>|<driveno>|\"-\"]\n"); 00547 printf(" [--verbose <level>] [--blank_fast|--blank_full]\n"); 00548 printf(" [--burn_for_real|--try_to_simulate] [--stdin_size <bytes>]\n"); 00549 printf(" [<imagefile>|\"-\"]\n"); 00550 printf("Examples\n"); 00551 printf("A bus scan (needs rw-permissions to see a drive):\n"); 00552 printf(" %s --drive -\n",argv[0]); 00553 printf("Burn a file to drive chosen by number:\n"); 00554 printf(" %s --drive 0 --burn_for_real my_image_file\n", 00555 argv[0]); 00556 printf("Burn a file to drive chosen by persistent address:\n"); 00557 printf(" %s --drive /dev/hdc --burn_for_real my_image_file\n", argv[0]); 00558 printf("Blank a used CD-RW (is combinable with burning in one run):\n"); 00559 printf(" %s --drive 0 --blank_fast\n",argv[0]); 00560 printf("Burn a compressed afio archive on-the-fly, pad up to 700 MB:\n"); 00561 printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n"); 00562 printf(" %s --drive /dev/hdc --burn_for_real --stdin_size 734003200 -\n", argv[0]); 00563 printf("To be read from *not mounted* CD via:\n"); 00564 printf(" afio -tvZ /dev/hdc\n"); 00565 printf("Program tar would need a clean EOF which our padded CD cannot deliver.\n"); 00566 if (insuffient_parameters) 00567 return 6; 00568 } 00569 return 0; 00570 }
int main | ( | int | argc, | |
char ** | argv | |||
) |
Definition at line 573 of file libburner.c.
References BURN_DRIVE_ADR_LEN, burn_drive_release(), burn_finish(), burn_initialize(), drive_is_grabbed, drive_list, libburner_aquire_drive(), libburner_blank_disc(), libburner_payload(), libburner_regrab(), and libburner_setup().
00574 { 00575 int driveno, ret, do_blank; 00576 char source_adr[4096], drive_adr[BURN_DRIVE_ADR_LEN]; 00577 off_t stdin_size; 00578 00579 ret = libburner_setup(argc, argv, drive_adr, &driveno, &do_blank, 00580 source_adr, &stdin_size); 00581 if (ret) 00582 exit(ret); 00583 00584 printf("Initializing library ...\n"); 00585 if (burn_initialize()) 00586 printf("Done\n"); 00587 else { 00588 printf("FAILED\n"); 00589 fprintf(stderr,"\nFATAL: Failed to initialize libburn.\n"); 00590 exit(33); 00591 } 00592 00593 /** Note: driveno might change its value in this call */ 00594 ret = libburner_aquire_drive(drive_adr, &driveno); 00595 if (ret<=0) { 00596 fprintf(stderr,"\nFATAL: Failed to aquire drive.\n"); 00597 { ret = 34; goto finish_libburn; } 00598 } 00599 if (ret == 2) 00600 { ret = 0; goto release_drive; } 00601 if (do_blank) { 00602 ret = libburner_blank_disc(drive_list[driveno].drive, 00603 do_blank == 1); 00604 if (ret<=0) 00605 { ret = 36; goto release_drive; } 00606 if (ret != 2 && source_adr[0] != 0) 00607 ret = libburner_regrab(drive_list[driveno].drive); 00608 if (ret<=0) { 00609 fprintf(stderr, 00610 "FATAL: Cannot release and grab again drive after blanking\n"); 00611 { ret = 37; goto finish_libburn; } 00612 } 00613 } 00614 if (source_adr[0] != 0) { 00615 ret = libburner_payload(drive_list[driveno].drive, source_adr, 00616 stdin_size); 00617 if (ret<=0) 00618 { ret = 38; goto release_drive; } 00619 } 00620 ret = 0; 00621 release_drive:; 00622 if (drive_is_grabbed) 00623 burn_drive_release(drive_list[driveno].drive, 0); 00624 00625 finish_libburn:; 00626 /* This app does not bother to know about exact scan state. 00627 Better to accept a memory leak here. We are done anyway. */ 00628 /* burn_drive_info_free(drive_list); */ 00629 00630 burn_finish(); 00631 return ret; 00632 }
unsigned int drive_count [static] |
If you start a long lasting operation with drive_count > 1 then you are not friendly to the users of other drives on those systems.
Beware.
Definition at line 70 of file libburner.c.
Referenced by libburner_aquire_by_driveno().
int drive_is_grabbed = 0 [static] |
This variable indicates wether the drive is grabbed and must be finally released.
Definition at line 74 of file libburner.c.
Referenced by libburner_aquire_by_adr(), libburner_aquire_by_driveno(), libburner_regrab(), and main().
struct burn_drive_info* drive_list [static] |
This list will hold the drives known to libburn.
This might be all CD drives of the system and thus might impose severe impact on the system.
Definition at line 66 of file libburner.c.
Referenced by libburner_aquire_by_adr(), libburner_aquire_by_driveno(), and main().
int simulate_burn = 0 [static] |
Here you may enable simulated burn by default.
This does not apply to blanking. Anyway, some CD recorders obey the request to simulate, some do not. Explicit options are: --burn_for_real and --try_to_simulate
Definition at line 81 of file libburner.c.
Referenced by libburner_payload(), and libburner_setup().