#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 <sys/stat.h>
#include <fcntl.h>
Go to the source code of this file.
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 or unformatted DVD-RW ready for thorough re-usal. | |
int | libburner_format (struct burn_drive *drive) |
Formats unformatted DVD-RW to profile 0013h "Restricted Overwrite" which needs no blanking for re-use but is not capable of multi-session. | |
int | libburner_payload (struct burn_drive *drive, char source_adr[][4096], int source_adr_count, int multi, int simulate_burn, int all_tracks_type) |
Brings preformatted track images (ISO 9660, audio, . | |
int | libburner_setup (int argc, char **argv) |
Converts command line arguments into above setup parameters. | |
int | main (int argc, char **argv) |
Variables | |
static struct burn_drive_info * | drive_list |
Overview. | |
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 | current_profile = -1 |
A number and a text describing the type of media in aquired drive. | |
static char | current_profile_name [80] = {""} |
static char | drive_adr [BURN_DRIVE_ADR_LEN] = {""} |
The setup parameters of libburner. | |
static int | driveno = 0 |
static int | do_blank = 0 |
static char | source_adr [99][4096] |
static int | source_adr_count = 0 |
static int | do_multi = 0 |
static int | simulate_burn = 0 |
static int | all_tracks_type = BURN_MODE1 |
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 123 of file libburner.c.
References BURN_DRIVE_ADR_LEN, burn_drive_convert_fs_adr(), burn_drive_scan_and_grab(), and drive_is_grabbed.
Referenced by libburner_aquire_drive().
00124 { 00125 int ret; 00126 char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; 00127 00128 /* Some not-so-harmless drive addresses get blocked in this demo */ 00129 if (strncmp(drive_adr, "stdio:/dev/fd/", 14) == 0 || 00130 strcmp(drive_adr, "stdio:-") == 0) { 00131 fprintf(stderr, "Will not work with pseudo-drive '%s'\n", 00132 drive_adr); 00133 return 0; 00134 } 00135 00136 /* This tries to resolve links or alternative device files */ 00137 ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr); 00138 if (ret<=0) { 00139 fprintf(stderr, "Address does not lead to a CD burner: '%s'\n", 00140 drive_adr); 00141 return 0; 00142 } 00143 fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr); 00144 ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1); 00145 if (ret <= 0) { 00146 fprintf(stderr,"FAILURE with persistent drive address '%s'\n", 00147 libburn_drive_adr); 00148 } else { 00149 fprintf(stderr,"Done\n"); 00150 drive_is_grabbed = 1; 00151 } 00152 return ret; 00153 }
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 168 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, burn_drive_info::product, and burn_drive_info::vendor.
Referenced by libburner_aquire_drive().
00169 { 00170 char adr[BURN_DRIVE_ADR_LEN]; 00171 int ret, i; 00172 00173 printf("Beginning to scan for devices ...\n"); 00174 while (!burn_drive_scan(&drive_list, &drive_count)) 00175 usleep(100002); 00176 if (drive_count <= 0 && *driveno >= 0) { 00177 printf("FAILED (no drives found)\n"); 00178 return 0; 00179 } 00180 printf("Done\n"); 00181 00182 /* 00183 Interactive programs may choose the drive number at this moment. 00184 00185 drive[0] to drive[drive_count-1] are struct burn_drive_info 00186 as defined in libburn/libburn.h . This structure is part of API 00187 and thus will strive for future compatibility on source level. 00188 Have a look at the info offered. 00189 Caution: do not take .location for drive address. Always use 00190 burn_drive_get_adr() or you might become incompatible 00191 in future. 00192 Note: bugs with struct burn_drive_info - if any - will not be 00193 easy to fix. Please report them but also strive for 00194 workarounds on application level. 00195 */ 00196 printf("\nOverview of accessible drives (%d found) :\n", 00197 drive_count); 00198 printf("-----------------------------------------------------------------------------\n"); 00199 for (i = 0; i < drive_count; i++) { 00200 if (burn_drive_get_adr(&(drive_list[i]), adr) <=0) 00201 strcpy(adr, "-get_adr_failed-"); 00202 printf("%d --drive '%s' : '%s' '%s'\n", 00203 i,adr,drive_list[i].vendor,drive_list[i].product); 00204 } 00205 printf("-----------------------------------------------------------------------------\n\n"); 00206 00207 /* 00208 On multi-drive systems save yourself from sysadmins' revenge. 00209 00210 Be aware that you hold reserved all available drives at this point. 00211 So either make your choice quick enough not to annoy other system 00212 users, or set free the drives for a while. 00213 00214 The tested way of setting free all drives is to shutdown the library 00215 and to restart when the choice has been made. The list of selectable 00216 drives should also hold persistent drive addresses as obtained 00217 above by burn_drive_get_adr(). By such an address one may use 00218 burn_drive_scan_and_grab() to finally aquire exactly one drive. 00219 00220 A not yet tested shortcut should be to call burn_drive_info_free() 00221 and to call either burn_drive_scan() or burn_drive_scan_and_grab() 00222 before accessing any drives again. 00223 00224 In both cases you have to be aware that the desired drive might get 00225 aquired in the meantime by another user resp. libburn process. 00226 */ 00227 00228 /* We already made our choice via command line. (default is 0) 00229 So we just have to keep our desired drive and drop all others. 00230 No other libburn instance will have a chance to steal our drive. 00231 */ 00232 if (*driveno < 0) { 00233 printf("Pseudo-drive \"-\" given : bus scanning done.\n"); 00234 return 2; /* the program will end after this */ 00235 } 00236 if (drive_count <= *driveno) { 00237 fprintf(stderr, 00238 "Found only %d drives. Number %d not available.\n", 00239 drive_count, *driveno); 00240 return 0; /* the program will end after this */ 00241 } 00242 00243 /* Drop all drives which we do not want to use */ 00244 for (i = 0; i < drive_count; i++) { 00245 if (i == *driveno) /* the one drive we want to keep */ 00246 continue; 00247 ret = burn_drive_info_forget(&(drive_list[i]),0); 00248 if (ret != 1) 00249 fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n", 00250 i, ret); 00251 else 00252 printf("Dropped unwanted drive %d\n",i); 00253 } 00254 /* Make the one we want ready for blanking or burning */ 00255 ret= burn_drive_grab(drive_list[*driveno].drive, 1); 00256 if (ret != 1) 00257 return 0; 00258 drive_is_grabbed = 1; 00259 return 1; 00260 }
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 101 of file libburner.c.
References burn_disc_get_profile(), current_profile, current_profile_name, burn_drive_info::drive, libburner_aquire_by_adr(), and libburner_aquire_by_driveno().
Referenced by main().
00102 { 00103 int ret; 00104 00105 if(drive_adr != NULL && drive_adr[0] != 0) 00106 ret = libburner_aquire_by_adr(drive_adr); 00107 else 00108 ret = libburner_aquire_by_driveno(driveno); 00109 if (ret <= 0 || *driveno <= 0) 00110 return ret; 00111 burn_disc_get_profile(drive_list[0].drive, ¤t_profile, 00112 current_profile_name); 00113 if (current_profile_name[0]) 00114 printf("Detected media type: %s\n", current_profile_name); 00115 return 1; 00116 }
int libburner_blank_disc | ( | struct burn_drive * | drive, | |
int | blank_fast | |||
) |
Makes a previously used CD-RW or unformatted DVD-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 signal handling to wait the normal blanking timespan until it can allow the process to end. External kill -9 will not help the drive.
Definition at line 271 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_drive_get_status(), BURN_DRIVE_IDLE, current_profile, burn_progress::sector, and burn_progress::sectors.
Referenced by main().
00272 { 00273 enum burn_disc_status disc_state; 00274 struct burn_progress p; 00275 double percent = 1.0; 00276 00277 disc_state = burn_disc_get_status(drive); 00278 printf( 00279 "Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n", 00280 disc_state); 00281 if (current_profile == 0x13) { 00282 ; /* formatted DVD-RW will get blanked to sequential state */ 00283 } else if (disc_state == BURN_DISC_BLANK) { 00284 fprintf(stderr, 00285 "IDLE: Blank media detected. Will leave it untouched\n"); 00286 return 2; 00287 } else if (disc_state == BURN_DISC_FULL || 00288 disc_state == BURN_DISC_APPENDABLE) { 00289 ; /* this is what libburner is willing to blank */ 00290 } else if (disc_state == BURN_DISC_EMPTY) { 00291 fprintf(stderr,"FATAL: No media detected in drive\n"); 00292 return 0; 00293 } else { 00294 fprintf(stderr, 00295 "FATAL: Unsuitable drive and media state\n"); 00296 return 0; 00297 } 00298 if(!burn_disc_erasable(drive)) { 00299 fprintf(stderr, 00300 "FATAL : Media is not of erasable type\n"); 00301 return 0; 00302 } 00303 printf( 00304 "Beginning to %s-blank media.\n", (blank_fast?"fast":"full")); 00305 burn_disc_erase(drive, blank_fast); 00306 sleep(1); 00307 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { 00308 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ 00309 percent = 1.0 + ((double) p.sector+1.0) 00310 / ((double) p.sectors) * 98.0; 00311 printf("Blanking ( %.1f%% done )\n", percent); 00312 sleep(1); 00313 } 00314 printf("Done\n"); 00315 return 1; 00316 }
int libburner_format | ( | struct burn_drive * | drive | ) |
Formats unformatted DVD-RW to profile 0013h "Restricted Overwrite" which needs no blanking for re-use but is not capable of multi-session.
Expect a behavior similar to blanking with unusual noises from the drive.
Formats unformatted BD-RE to default size. This will allocate some reserve space, test for bad blocks and make the media ready for writing. Expect a very long run time.
Formats unformatted blank BD-R to hold a default amount of spare blocks for eventual mishaps during writing. If BD-R get written without being formatted, then they get no such reserve and will burn at full speed.
Definition at line 331 of file libburner.c.
References BURN_DISC_BLANK, burn_disc_format(), burn_disc_get_formats(), burn_disc_get_profile(), burn_disc_get_status(), burn_drive_get_status(), BURN_DRIVE_IDLE, BURN_FORMAT_IS_UNFORMATTED, current_profile, current_profile_name, burn_progress::sector, and burn_progress::sectors.
Referenced by main().
00332 { 00333 struct burn_progress p; 00334 double percent = 1.0; 00335 int ret, status, num_formats, format_flag= 0; 00336 off_t size = 0; 00337 unsigned dummy; 00338 enum burn_disc_status disc_state; 00339 00340 if (current_profile == 0x13) { 00341 fprintf(stderr, "IDLE: DVD-RW media is already formatted\n"); 00342 return 2; 00343 } else if (current_profile == 0x41 || current_profile == 0x43) { 00344 disc_state = burn_disc_get_status(drive); 00345 if (disc_state != BURN_DISC_BLANK && current_profile == 0x41) { 00346 fprintf(stderr, 00347 "FATAL: BD-R is not blank. Cannot format.\n"); 00348 return 0; 00349 } 00350 ret = burn_disc_get_formats(drive, &status, &size, &dummy, 00351 &num_formats); 00352 if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) { 00353 fprintf(stderr, 00354 "IDLE: BD media is already formatted\n"); 00355 return 2; 00356 } 00357 size = 0; /* does not really matter */ 00358 format_flag = 3<<1; /* format to default size, no quick */ 00359 } else if (current_profile == 0x14) { /* sequential DVD-RW */ 00360 size = 128 * 1024 * 1024; 00361 format_flag = 1; /* write initial 128 MiB */ 00362 } else { 00363 fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n"); 00364 return 0; 00365 } 00366 00367 printf("Beginning to format media.\n"); 00368 burn_disc_format(drive, size, format_flag); 00369 00370 sleep(1); 00371 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { 00372 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ 00373 percent = 1.0 + ((double) p.sector+1.0) 00374 / ((double) p.sectors) * 98.0; 00375 printf("Formatting ( %.1f%% done )\n", percent); 00376 sleep(1); 00377 } 00378 burn_disc_get_profile(drive_list[0].drive, ¤t_profile, 00379 current_profile_name); 00380 if (current_profile == 0x14 || current_profile == 0x13) 00381 printf("Media type now: %4.4xh \"%s\"\n", 00382 current_profile, current_profile_name); 00383 if (current_profile == 0x14) { 00384 fprintf(stderr, 00385 "FATAL: Failed to change media profile to desired value\n"); 00386 return 0; 00387 } 00388 return 1; 00389 }
int libburner_payload | ( | struct burn_drive * | drive, | |
char | source_adr[][4096], | |||
int | source_adr_count, | |||
int | multi, | |||
int | simulate_burn, | |||
int | all_tracks_type | |||
) |
Brings preformatted track images (ISO 9660, audio, .
..) onto media. To make sure a data image is fully readable on any Linux machine, this function adds 300 kiB of padding to the (usualy single) track. Audio tracks get padded to complete their last sector. A fifo of 4 MB is installed between each track and its data source. Each of the 4 MB buffers gets allocated automatically as soon as a track begins to be processed and it gets freed as soon as the track is done. The fifos do not wait for buffer fill but writing starts immediately.
In case of external signals expect abort handling of an ongoing burn to last up to a minute. Wait the normal burning timespan before any kill -9.
For simplicity, this function allows memory leaks in case of failure. In apps which do not abort immediately, one should clean up better.
Definition at line 407 of file libburner.c.
References BURN_AUDIO, 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_write(), burn_drive_get_status(), BURN_DRIVE_IDLE, burn_drive_set_speed(), BURN_DRIVE_SPAWNING, burn_fd_source_new(), burn_fifo_inquire_status(), burn_fifo_source_new(), BURN_MODE1, BURN_POS_END, BURN_REASONS_LEN, burn_session_add_track(), burn_session_create(), burn_session_free(), burn_source_free(), BURN_SOURCE_OK, burn_track_create(), burn_track_define_data(), burn_track_free(), burn_track_set_source(), BURN_WRITE_NONE, burn_write_opts_auto_write_type(), burn_write_opts_free(), burn_write_opts_new(), burn_write_opts_set_multi(), burn_write_opts_set_perform_opc(), burn_write_opts_set_simulate(), burn_write_opts_set_underrun_proof(), current_profile, burn_progress::sector, burn_progress::sectors, and burn_progress::track.
Referenced by main().
00410 { 00411 struct burn_source *data_src, *fifo_src[99]; 00412 struct burn_disc *target_disc; 00413 struct burn_session *session; 00414 struct burn_write_opts *burn_options; 00415 enum burn_disc_status disc_state; 00416 struct burn_track *track, *tracklist[99]; 00417 struct burn_progress progress; 00418 time_t start_time; 00419 int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd; 00420 int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */ 00421 off_t fixed_size; 00422 char *adr, reasons[BURN_REASONS_LEN]; 00423 struct stat stbuf; 00424 00425 if (all_tracks_type != BURN_AUDIO) { 00426 all_tracks_type = BURN_MODE1; 00427 /* a padding of 300 kiB helps to avoid the read-ahead bug */ 00428 padding = 300*1024; 00429 fifo_chunksize = 2048; 00430 fifo_chunks = 2048; /* 4 MB fifo */ 00431 } 00432 00433 target_disc = burn_disc_create(); 00434 session = burn_session_create(); 00435 burn_disc_add_session(target_disc, session, BURN_POS_END); 00436 00437 for (trackno = 0 ; trackno < source_adr_count; trackno++) { 00438 tracklist[trackno] = track = burn_track_create(); 00439 burn_track_define_data(track, 0, padding, 1, all_tracks_type); 00440 00441 /* Open file descriptor to source of track data */ 00442 adr = source_adr[trackno]; 00443 fixed_size = 0; 00444 if (adr[0] == '-' && adr[1] == 0) { 00445 fd = 0; 00446 } else { 00447 fd = open(adr, O_RDONLY); 00448 if (fd>=0) 00449 if (fstat(fd,&stbuf)!=-1) 00450 if((stbuf.st_mode&S_IFMT)==S_IFREG) 00451 fixed_size = stbuf.st_size; 00452 } 00453 if (fixed_size==0) 00454 unpredicted_size = 1; 00455 00456 /* Convert this filedescriptor into a burn_source object */ 00457 data_src = NULL; 00458 if (fd>=0) 00459 data_src = burn_fd_source_new(fd, -1, fixed_size); 00460 if (data_src == NULL) { 00461 fprintf(stderr, 00462 "FATAL: Could not open data source '%s'.\n",adr); 00463 if(errno!=0) 00464 fprintf(stderr,"(Most recent system error: %s )\n", 00465 strerror(errno)); 00466 return 0; 00467 } 00468 /* Install a fifo object on top of that data source object */ 00469 fifo_src[trackno] = burn_fifo_source_new(data_src, 00470 fifo_chunksize, fifo_chunks, 0); 00471 if (fifo_src[trackno] == NULL) { 00472 fprintf(stderr, 00473 "FATAL: Could not create fifo object of 4 MB\n"); 00474 return 0; 00475 } 00476 00477 /* Use the fifo object as data source for the track */ 00478 if (burn_track_set_source(track, fifo_src[trackno]) 00479 != BURN_SOURCE_OK) { 00480 fprintf(stderr, 00481 "FATAL: Cannot attach source object to track object\n"); 00482 return 0; 00483 } 00484 00485 burn_session_add_track(session, track, BURN_POS_END); 00486 printf("Track %d : source is '%s'\n", trackno+1, adr); 00487 00488 /* Give up local reference to the data burn_source object */ 00489 burn_source_free(data_src); 00490 00491 } /* trackno loop end */ 00492 00493 /* Evaluate drive and media */ 00494 disc_state = burn_disc_get_status(drive); 00495 if (disc_state != BURN_DISC_BLANK && 00496 disc_state != BURN_DISC_APPENDABLE) { 00497 if (disc_state == BURN_DISC_FULL) { 00498 fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n"); 00499 if (burn_disc_erasable(drive)) 00500 fprintf(stderr, "HINT: Try --blank_fast\n\n"); 00501 } else if (disc_state == BURN_DISC_EMPTY) 00502 fprintf(stderr,"FATAL: No media detected in drive\n"); 00503 else 00504 fprintf(stderr, 00505 "FATAL: Cannot recognize state of drive and media\n"); 00506 return 0; 00507 } 00508 00509 burn_options = burn_write_opts_new(drive); 00510 burn_write_opts_set_perform_opc(burn_options, 0); 00511 burn_write_opts_set_multi(burn_options, !!multi); 00512 if(simulate_burn) 00513 printf("\n*** Will TRY to SIMULATE burning ***\n\n"); 00514 burn_write_opts_set_simulate(burn_options, simulate_burn); 00515 burn_drive_set_speed(drive, 0, 0); 00516 burn_write_opts_set_underrun_proof(burn_options, 1); 00517 if (burn_write_opts_auto_write_type(burn_options, target_disc, 00518 reasons, 0) == BURN_WRITE_NONE) { 00519 fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n"); 00520 fprintf(stderr, "Reasons given:\n%s\n", reasons); 00521 return 0; 00522 } 00523 00524 printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n"); 00525 start_time = time(0); 00526 burn_disc_write(burn_options, target_disc); 00527 00528 burn_write_opts_free(burn_options); 00529 while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) 00530 usleep(100002); 00531 while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { 00532 if (progress.sectors <= 0 || 00533 (progress.sector >= progress.sectors - 1 && 00534 !unpredicted_size) || 00535 (unpredicted_size && progress.sector == last_sector)) 00536 printf( 00537 "Thank you for being patient since %d seconds.", 00538 (int) (time(0) - start_time)); 00539 else if(unpredicted_size) 00540 printf("Track %d : sector %d", progress.track+1, 00541 progress.sector); 00542 else 00543 printf("Track %d : sector %d of %d",progress.track+1, 00544 progress.sector, progress.sectors); 00545 last_sector = progress.sector; 00546 if (progress.track >= 0 && progress.track < source_adr_count) { 00547 int size, free_bytes, ret; 00548 char *status_text; 00549 00550 ret = burn_fifo_inquire_status( 00551 fifo_src[progress.track], &size, &free_bytes, 00552 &status_text); 00553 if (ret >= 0 ) 00554 printf(" [fifo %s, %2d%% fill]", status_text, 00555 (int) (100.0 - 100.0 * 00556 ((double) free_bytes) / 00557 (double) size)); 00558 } 00559 printf("\n"); 00560 sleep(1); 00561 } 00562 printf("\n"); 00563 00564 for (trackno = 0 ; trackno < source_adr_count; trackno++) { 00565 burn_source_free(fifo_src[trackno]); 00566 burn_track_free(tracklist[trackno]); 00567 } 00568 burn_session_free(session); 00569 burn_disc_free(target_disc); 00570 if (multi && current_profile != 0x1a && current_profile != 0x13 && 00571 current_profile != 0x12 && current_profile != 0x43) 00572 /* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */ 00573 printf("NOTE: Media left appendable.\n"); 00574 if (simulate_burn) 00575 printf("\n*** Did TRY to SIMULATE burning ***\n\n"); 00576 return 1; 00577 }
int libburner_setup | ( | int | argc, | |
char ** | argv | |||
) |
Converts command line arguments into above setup parameters.
Definition at line 593 of file libburner.c.
References all_tracks_type, BURN_AUDIO, BURN_DRIVE_ADR_LEN, do_blank, do_multi, drive_adr, driveno, simulate_burn, source_adr, and source_adr_count.
Referenced by main().
00594 { 00595 int i, insuffient_parameters = 0, print_help = 0; 00596 00597 for (i = 1; i < argc; ++i) { 00598 if (!strcmp(argv[i], "--audio")) { 00599 all_tracks_type = BURN_AUDIO; 00600 00601 } else if (!strcmp(argv[i], "--blank_fast")) { 00602 do_blank = 1; 00603 00604 } else if (!strcmp(argv[i], "--blank_full")) { 00605 do_blank = 2; 00606 00607 } else if (!strcmp(argv[i], "--burn_for_real")) { 00608 simulate_burn = 0; 00609 00610 } else if (!strcmp(argv[i], "--drive")) { 00611 ++i; 00612 if (i >= argc) { 00613 fprintf(stderr,"--drive requires an argument\n"); 00614 return 1; 00615 } else if (strcmp(argv[i], "-") == 0) { 00616 drive_adr[0] = 0; 00617 driveno = -1; 00618 } else if (isdigit(argv[i][0])) { 00619 drive_adr[0] = 0; 00620 driveno = atoi(argv[i]); 00621 } else { 00622 if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) { 00623 fprintf(stderr,"--drive address too long (max. %d)\n", 00624 BURN_DRIVE_ADR_LEN-1); 00625 return 2; 00626 } 00627 strcpy(drive_adr, argv[i]); 00628 } 00629 } else if ((!strcmp(argv[i], "--format_overwrite")) || 00630 (!strcmp(argv[i], "--format"))) { 00631 do_blank = 101; 00632 00633 } else if (!strcmp(argv[i], "--multi")) { 00634 do_multi = 1; 00635 00636 } else if (!strcmp(argv[i], "--stdin_size")) { /* obsoleted */ 00637 i++; 00638 00639 } else if (!strcmp(argv[i], "--try_to_simulate")) { 00640 simulate_burn = 1; 00641 00642 } else if (!strcmp(argv[i], "--help")) { 00643 print_help = 1; 00644 00645 } else if (!strncmp(argv[i], "--",2)) { 00646 fprintf(stderr, "Unidentified option: %s\n", argv[i]); 00647 return 7; 00648 } else { 00649 if(strlen(argv[i]) >= 4096) { 00650 fprintf(stderr, "Source address too long (max. %d)\n", 4096-1); 00651 return 5; 00652 } 00653 if(source_adr_count >= 99) { 00654 fprintf(stderr, "Too many tracks (max. 99)\n"); 00655 return 6; 00656 } 00657 strcpy(source_adr[source_adr_count], argv[i]); 00658 source_adr_count++; 00659 } 00660 } 00661 insuffient_parameters = 1; 00662 if (driveno < 0) 00663 insuffient_parameters = 0; 00664 if (source_adr_count > 0) 00665 insuffient_parameters = 0; 00666 if (do_blank) 00667 insuffient_parameters = 0; 00668 if (print_help || insuffient_parameters ) { 00669 printf("Usage: %s\n", argv[0]); 00670 printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n"); 00671 printf(" [--blank_fast|--blank_full|--format] [--try_to_simulate]\n"); 00672 printf(" [--multi] [<one or more imagefiles>|\"-\"]\n"); 00673 printf("Examples\n"); 00674 printf("A bus scan (needs rw-permissions to see a drive):\n"); 00675 printf(" %s --drive -\n",argv[0]); 00676 printf("Burn a file to drive chosen by number, leave appendable:\n"); 00677 printf(" %s --drive 0 --multi my_image_file\n", argv[0]); 00678 printf("Burn a file to drive chosen by persistent address, close:\n"); 00679 printf(" %s --drive /dev/hdc my_image_file\n", argv[0]); 00680 printf("Blank a used CD-RW (is combinable with burning in one run):\n"); 00681 printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]); 00682 printf("Blank a used DVD-RW (is combinable with burning in one run):\n"); 00683 printf(" %s --drive /dev/hdc --blank_full\n",argv[0]); 00684 printf("Format a DVD-RW, BD-RE or BD-R:\n"); 00685 printf(" %s --drive /dev/hdc --format\n", argv[0]); 00686 printf("Burn two audio tracks (to CD only):\n"); 00687 printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n"); 00688 printf(" test/dewav /path/to/track2.wav -o track2.cd\n"); 00689 printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]); 00690 printf("Burn a compressed afio archive on-the-fly:\n"); 00691 printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n"); 00692 printf(" %s --drive /dev/hdc -\n", argv[0]); 00693 printf("To be read from *not mounted* media via: afio -tvZ /dev/hdc\n"); 00694 if (insuffient_parameters) 00695 return 6; 00696 } 00697 return 0; 00698 }
int main | ( | int | argc, | |
char ** | argv | |||
) |
Note: driveno might change its value in this call
Definition at line 701 of file libburner.c.
References all_tracks_type, burn_drive_release(), burn_finish(), burn_initialize(), burn_msgs_set_severities(), burn_set_signal_handling(), do_blank, do_multi, drive_adr, drive_is_grabbed, driveno, libburner_aquire_drive(), libburner_blank_disc(), libburner_format(), libburner_payload(), libburner_setup(), simulate_burn, source_adr, and source_adr_count.
00702 { 00703 int ret; 00704 00705 ret = libburner_setup(argc, argv); 00706 if (ret) 00707 exit(ret); 00708 00709 printf("Initializing libburnia-project.org ...\n"); 00710 if (burn_initialize()) 00711 printf("Done\n"); 00712 else { 00713 printf("FAILED\n"); 00714 fprintf(stderr,"\nFATAL: Failed to initialize.\n"); 00715 exit(33); 00716 } 00717 00718 /* Print messages of severity SORRY or more directly to stderr */ 00719 burn_msgs_set_severities("NEVER", "SORRY", "libburner : "); 00720 00721 /* Activate the default signal handler which eventually will try to 00722 properly shutdown drive and library on aborting events. */ 00723 burn_set_signal_handling("libburner : ", NULL, 0); 00724 00725 /** Note: driveno might change its value in this call */ 00726 ret = libburner_aquire_drive(drive_adr, &driveno); 00727 if (ret<=0) { 00728 fprintf(stderr,"\nFATAL: Failed to aquire drive.\n"); 00729 { ret = 34; goto finish_libburn; } 00730 } 00731 if (ret == 2) 00732 { ret = 0; goto release_drive; } 00733 if (do_blank) { 00734 if (do_blank > 100) 00735 ret = libburner_format(drive_list[driveno].drive); 00736 else 00737 ret = libburner_blank_disc(drive_list[driveno].drive, 00738 do_blank == 1); 00739 if (ret<=0) 00740 { ret = 36; goto release_drive; } 00741 } 00742 if (source_adr_count > 0) { 00743 ret = libburner_payload(drive_list[driveno].drive, 00744 source_adr, source_adr_count, 00745 do_multi, simulate_burn, all_tracks_type); 00746 if (ret<=0) 00747 { ret = 38; goto release_drive; } 00748 } 00749 ret = 0; 00750 release_drive:; 00751 if (drive_is_grabbed) 00752 burn_drive_release(drive_list[driveno].drive, 0); 00753 00754 finish_libburn:; 00755 /* This app does not bother to know about exact scan state. 00756 Better to accept a memory leak here. We are done anyway. */ 00757 /* burn_drive_info_free(drive_list); */ 00758 00759 burn_finish(); 00760 exit(ret); 00761 }
int all_tracks_type = BURN_MODE1 [static] |
Definition at line 588 of file libburner.c.
Referenced by libburner_setup(), and main().
int current_profile = -1 [static] |
A number and a text describing the type of media in aquired drive.
Definition at line 78 of file libburner.c.
Referenced by libburner_aquire_drive(), libburner_blank_disc(), libburner_format(), and libburner_payload().
char current_profile_name[80] = {""} [static] |
Definition at line 79 of file libburner.c.
Referenced by libburner_aquire_drive(), and libburner_format().
int do_blank = 0 [static] |
Definition at line 583 of file libburner.c.
Referenced by libburner_setup(), and main().
int do_multi = 0 [static] |
Definition at line 586 of file libburner.c.
Referenced by libburner_setup(), and main().
char drive_adr[BURN_DRIVE_ADR_LEN] = {""} [static] |
The setup parameters of libburner.
Definition at line 581 of file libburner.c.
Referenced by libburner_setup(), and main().
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 71 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 75 of file libburner.c.
Referenced by libburner_aquire_by_adr(), libburner_aquire_by_driveno(), and main().
struct burn_drive_info* drive_list [static] |
Overview.
libburner is a minimal demo application for the library libburn as provided on http://libburnia-project.org . It can list the available devices, can blank a CD-RW or DVD-RW, can format DVD-RW and BD, can burn to CD-R, CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RW, DVD-RAM, BD-R, BD-RE. Not supported yet: DVD-R/DL.
It's main purpose, nevertheless, is to show you how to use libburn and also to serve the libburnia 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() and provide some signal and abort handling, e.g. by the builtin handler, by burn_set_signal_handling() 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() or you can format a DVD-RW to profile "Restricted Overwrite" (needed once) or an unused BD to default size with spare blocks libburner_format() With the aquired drive you can burn to CD, DVD, BD libburner_payload() When everything is done, main() releases the drive and shuts down libburn: burn_drive_release(); burn_finish() See this for the decisive API specs . libburn.h is The Original For simplicity i use global variables to represent the drives. Drives are systemwide global, so we do not give away much of good style. 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 67 of file libburner.c.
int driveno = 0 [static] |
Definition at line 582 of file libburner.c.
Referenced by libburner_setup(), and main().
int simulate_burn = 0 [static] |
Definition at line 587 of file libburner.c.
Referenced by libburner_setup(), and main().
char source_adr[99][4096] [static] |
Definition at line 584 of file libburner.c.
Referenced by libburner_setup(), and main().
int source_adr_count = 0 [static] |
Definition at line 585 of file libburner.c.
Referenced by libburner_setup(), and main().