#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 acquire 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 |
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 | current_profile = -1 |
A number and a text describing the type of media in acquired 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 147 of file libburner.c.
References BURN_DRIVE_ADR_LEN, burn_drive_convert_fs_adr(), burn_drive_scan_and_grab(), drive_is_grabbed, and drive_list.
Referenced by libburner_aquire_drive().
00148 { 00149 int ret; 00150 char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; 00151 00152 /* Some not-so-harmless drive addresses get blocked in this demo */ 00153 if (strncmp(drive_adr, "stdio:/dev/fd/", 14) == 0 || 00154 strcmp(drive_adr, "stdio:-") == 0) { 00155 fprintf(stderr, "Will not work with pseudo-drive '%s'\n", 00156 drive_adr); 00157 return 0; 00158 } 00159 00160 /* This tries to resolve links or alternative device files */ 00161 ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr); 00162 if (ret<=0) { 00163 fprintf(stderr, "Address does not lead to a CD burner: '%s'\n", 00164 drive_adr); 00165 return 0; 00166 } 00167 fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr); 00168 ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1); 00169 if (ret <= 0) { 00170 fprintf(stderr,"FAILURE with persistent drive address '%s'\n", 00171 libburn_drive_adr); 00172 } else { 00173 fprintf(stderr,"Done\n"); 00174 drive_is_grabbed = 1; 00175 } 00176 return ret; 00177 }
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 192 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().
00193 { 00194 char adr[BURN_DRIVE_ADR_LEN]; 00195 int ret, i; 00196 00197 printf("Beginning to scan for devices ...\n"); 00198 while (!burn_drive_scan(&drive_list, &drive_count)) 00199 usleep(100002); 00200 if (drive_count <= 0 && *driveno >= 0) { 00201 printf("FAILED (no drives found)\n"); 00202 return 0; 00203 } 00204 printf("Done\n"); 00205 00206 /* 00207 Interactive programs may choose the drive number at this moment. 00208 00209 drive[0] to drive[drive_count-1] are struct burn_drive_info 00210 as defined in libburn/libburn.h . This structure is part of API 00211 and thus will strive for future compatibility on source level. 00212 Have a look at the info offered. 00213 Caution: do not take .location for drive address. Always use 00214 burn_drive_get_adr() or you might become incompatible 00215 in future. 00216 Note: bugs with struct burn_drive_info - if any - will not be 00217 easy to fix. Please report them but also strive for 00218 workarounds on application level. 00219 */ 00220 printf("\nOverview of accessible drives (%d found) :\n", 00221 drive_count); 00222 printf("-----------------------------------------------------------------------------\n"); 00223 for (i = 0; i < (int) drive_count; i++) { 00224 if (burn_drive_get_adr(&(drive_list[i]), adr) <=0) 00225 strcpy(adr, "-get_adr_failed-"); 00226 printf("%d --drive '%s' : '%s' '%s'\n", 00227 i,adr,drive_list[i].vendor,drive_list[i].product); 00228 } 00229 printf("-----------------------------------------------------------------------------\n\n"); 00230 00231 /* 00232 On multi-drive systems save yourself from sysadmins' revenge. 00233 00234 Be aware that you hold reserved all available drives at this point. 00235 So either make your choice quick enough not to annoy other system 00236 users, or set free the drives for a while. 00237 00238 The tested way of setting free all drives is to shutdown the library 00239 and to restart when the choice has been made. The list of selectable 00240 drives should also hold persistent drive addresses as obtained 00241 above by burn_drive_get_adr(). By such an address one may use 00242 burn_drive_scan_and_grab() to finally acquire exactly one drive. 00243 00244 A not yet tested shortcut should be to call burn_drive_info_free() 00245 and to call either burn_drive_scan() or burn_drive_scan_and_grab() 00246 before accessing any drives again. 00247 00248 In both cases you have to be aware that the desired drive might get 00249 acquired in the meantime by another user or libburn process. 00250 */ 00251 00252 /* We already made our choice via command line. (default is 0) 00253 So we just have to keep our desired drive and drop all others. 00254 No other libburn instance will have a chance to steal our drive. 00255 */ 00256 if (*driveno < 0) { 00257 printf("Pseudo-drive \"-\" given : bus scanning done.\n"); 00258 return 2; /* the program will end after this */ 00259 } 00260 if ((int) drive_count <= *driveno) { 00261 fprintf(stderr, 00262 "Found only %d drives. Number %d not available.\n", 00263 drive_count, *driveno); 00264 return 0; /* the program will end after this */ 00265 } 00266 00267 /* Drop all drives which we do not want to use */ 00268 for (i = 0; i < (int) drive_count; i++) { 00269 if (i == *driveno) /* the one drive we want to keep */ 00270 continue; 00271 ret = burn_drive_info_forget(&(drive_list[i]),0); 00272 if (ret != 1) 00273 fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n", 00274 i, ret); 00275 else 00276 printf("Dropped unwanted drive %d\n",i); 00277 } 00278 /* Make the one we want ready for blanking or burning */ 00279 ret= burn_drive_grab(drive_list[*driveno].drive, 1); 00280 if (ret != 1) 00281 return 0; 00282 drive_is_grabbed = 1; 00283 return 1; 00284 }
int libburner_aquire_drive | ( | char * | drive_adr, | |
int * | driveno | |||
) |
You need to acquire 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 125 of file libburner.c.
References burn_disc_get_profile(), current_profile, current_profile_name, burn_drive_info::drive, drive_list, libburner_aquire_by_adr(), and libburner_aquire_by_driveno().
Referenced by main().
00126 { 00127 int ret; 00128 00129 if(drive_adr != NULL && drive_adr[0] != 0) 00130 ret = libburner_aquire_by_adr(drive_adr); 00131 else 00132 ret = libburner_aquire_by_driveno(driveno); 00133 if (ret <= 0 || *driveno <= 0) 00134 return ret; 00135 burn_disc_get_profile(drive_list[0].drive, ¤t_profile, 00136 current_profile_name); 00137 if (current_profile_name[0]) 00138 printf("Detected media type: %s\n", current_profile_name); 00139 return 1; 00140 }
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 295 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, burn_is_aborting(), burn_set_signal_handling(), current_profile, burn_progress::sector, and burn_progress::sectors.
Referenced by main().
00296 { 00297 enum burn_disc_status disc_state; 00298 struct burn_progress p; 00299 double percent = 1.0; 00300 00301 disc_state = burn_disc_get_status(drive); 00302 printf( 00303 "Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n", 00304 disc_state); 00305 if (current_profile == 0x13) { 00306 ; /* formatted DVD-RW will get blanked to sequential state */ 00307 } else if (disc_state == BURN_DISC_BLANK) { 00308 fprintf(stderr, 00309 "IDLE: Blank media detected. Will leave it untouched\n"); 00310 return 2; 00311 } else if (disc_state == BURN_DISC_FULL || 00312 disc_state == BURN_DISC_APPENDABLE) { 00313 ; /* this is what libburner is willing to blank */ 00314 } else if (disc_state == BURN_DISC_EMPTY) { 00315 fprintf(stderr,"FATAL: No media detected in drive\n"); 00316 return 0; 00317 } else { 00318 fprintf(stderr, 00319 "FATAL: Unsuitable drive and media state\n"); 00320 return 0; 00321 } 00322 if(!burn_disc_erasable(drive)) { 00323 fprintf(stderr, 00324 "FATAL : Media is not of erasable type\n"); 00325 return 0; 00326 } 00327 /* Switch to asynchronous signal handling for the time of waiting */ 00328 burn_set_signal_handling("libburner : ", NULL, 0x30); 00329 00330 printf("Beginning to %s-blank media.\n", (blank_fast?"fast":"full")); 00331 burn_disc_erase(drive, blank_fast); 00332 00333 sleep(1); 00334 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { 00335 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ 00336 percent = 1.0 + ((double) p.sector+1.0) 00337 / ((double) p.sectors) * 98.0; 00338 printf("Blanking ( %.1f%% done )\n", percent); 00339 sleep(1); 00340 } 00341 if (burn_is_aborting(0) > 0) 00342 return -1; 00343 /* Back to synchronous handling */ 00344 burn_set_signal_handling("libburner : ", NULL, 0x0); 00345 printf("Done\n"); 00346 return 1; 00347 }
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 362 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, burn_is_aborting(), burn_set_signal_handling(), current_profile, current_profile_name, drive_list, burn_progress::sector, and burn_progress::sectors.
Referenced by main().
00363 { 00364 struct burn_progress p; 00365 double percent = 1.0; 00366 int ret, status, num_formats, format_flag= 0; 00367 off_t size = 0; 00368 unsigned dummy; 00369 enum burn_disc_status disc_state; 00370 00371 if (current_profile == 0x13) { 00372 fprintf(stderr, "IDLE: DVD-RW media is already formatted\n"); 00373 return 2; 00374 } else if (current_profile == 0x41 || current_profile == 0x43) { 00375 disc_state = burn_disc_get_status(drive); 00376 if (disc_state != BURN_DISC_BLANK && current_profile == 0x41) { 00377 fprintf(stderr, 00378 "FATAL: BD-R is not blank. Cannot format.\n"); 00379 return 0; 00380 } 00381 ret = burn_disc_get_formats(drive, &status, &size, &dummy, 00382 &num_formats); 00383 if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) { 00384 fprintf(stderr, 00385 "IDLE: BD media is already formatted\n"); 00386 return 2; 00387 } 00388 size = 0; /* does not really matter */ 00389 format_flag = 3<<1; /* format to default size, no quick */ 00390 } else if (current_profile == 0x14) { /* sequential DVD-RW */ 00391 size = 128 * 1024 * 1024; 00392 format_flag = 1; /* write initial 128 MiB */ 00393 } else { 00394 fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n"); 00395 return 0; 00396 } 00397 burn_set_signal_handling("libburner : ", NULL, 0x30); 00398 00399 printf("Beginning to format media.\n"); 00400 burn_disc_format(drive, size, format_flag); 00401 00402 sleep(1); 00403 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { 00404 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ 00405 percent = 1.0 + ((double) p.sector+1.0) 00406 / ((double) p.sectors) * 98.0; 00407 printf("Formatting ( %.1f%% done )\n", percent); 00408 sleep(1); 00409 } 00410 if (burn_is_aborting(0) > 0) 00411 return -1; 00412 burn_set_signal_handling("libburner : ", NULL, 0x0); 00413 burn_disc_get_profile(drive_list[0].drive, ¤t_profile, 00414 current_profile_name); 00415 if (current_profile == 0x14 || current_profile == 0x13) 00416 printf("Media type now: %4.4xh \"%s\"\n", 00417 current_profile, current_profile_name); 00418 if (current_profile == 0x14) { 00419 fprintf(stderr, 00420 "FATAL: Failed to change media profile to desired value\n"); 00421 return 0; 00422 } 00423 return 1; 00424 }
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.
Definition at line 439 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_is_aborting(), BURN_MODE1, BURN_POS_END, BURN_REASONS_LEN, burn_session_add_track(), burn_session_create(), burn_session_free(), burn_set_signal_handling(), 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().
00442 { 00443 struct burn_source *data_src = NULL, *fifo_src[99]; 00444 struct burn_disc *target_disc = NULL; 00445 struct burn_session *session = NULL; 00446 struct burn_write_opts *burn_options = NULL; 00447 enum burn_disc_status disc_state; 00448 struct burn_track *track, *tracklist[99]; 00449 struct burn_progress progress; 00450 time_t start_time; 00451 int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd; 00452 int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */ 00453 int ret; 00454 off_t fixed_size; 00455 char *adr, reasons[BURN_REASONS_LEN]; 00456 struct stat stbuf; 00457 00458 for (trackno = 0 ; trackno < source_adr_count; trackno++) { 00459 fifo_src[trackno] = NULL; 00460 tracklist[trackno] = NULL; 00461 } 00462 00463 if (all_tracks_type != BURN_AUDIO) { 00464 all_tracks_type = BURN_MODE1; 00465 /* a padding of 300 kiB helps to avoid the read-ahead bug */ 00466 padding = 300*1024; 00467 fifo_chunksize = 2048; 00468 fifo_chunks = 2048; /* 4 MB fifo */ 00469 } 00470 00471 target_disc = burn_disc_create(); 00472 session = burn_session_create(); 00473 burn_disc_add_session(target_disc, session, BURN_POS_END); 00474 00475 for (trackno = 0 ; trackno < source_adr_count; trackno++) { 00476 tracklist[trackno] = track = burn_track_create(); 00477 burn_track_define_data(track, 0, padding, 1, all_tracks_type); 00478 00479 /* Open file descriptor to source of track data */ 00480 adr = source_adr[trackno]; 00481 fixed_size = 0; 00482 if (adr[0] == '-' && adr[1] == 0) { 00483 fd = 0; 00484 } else { 00485 fd = open(adr, O_RDONLY); 00486 if (fd>=0) 00487 if (fstat(fd,&stbuf)!=-1) 00488 if((stbuf.st_mode&S_IFMT)==S_IFREG) 00489 fixed_size = stbuf.st_size; 00490 } 00491 if (fixed_size==0) 00492 unpredicted_size = 1; 00493 00494 /* Convert this filedescriptor into a burn_source object */ 00495 data_src = NULL; 00496 if (fd >= 0) 00497 data_src = burn_fd_source_new(fd, -1, fixed_size); 00498 if (data_src == NULL) { 00499 fprintf(stderr, 00500 "FATAL: Could not open data source '%s'.\n",adr); 00501 if(errno!=0) 00502 fprintf(stderr,"(Most recent system error: %s )\n", 00503 strerror(errno)); 00504 {ret = 0; goto ex;} 00505 } 00506 /* Install a fifo object on top of that data source object */ 00507 fifo_src[trackno] = burn_fifo_source_new(data_src, 00508 fifo_chunksize, fifo_chunks, 0); 00509 if (fifo_src[trackno] == NULL) { 00510 fprintf(stderr, 00511 "FATAL: Could not create fifo object of 4 MB\n"); 00512 {ret = 0; goto ex;} 00513 } 00514 00515 /* Use the fifo object as data source for the track */ 00516 if (burn_track_set_source(track, fifo_src[trackno]) 00517 != BURN_SOURCE_OK) { 00518 fprintf(stderr, 00519 "FATAL: Cannot attach source object to track object\n"); 00520 {ret = 0; goto ex;} 00521 } 00522 00523 burn_session_add_track(session, track, BURN_POS_END); 00524 printf("Track %d : source is '%s'\n", trackno+1, adr); 00525 00526 /* Give up local reference to the data burn_source object */ 00527 burn_source_free(data_src); 00528 data_src = NULL; 00529 00530 } /* trackno loop end */ 00531 00532 /* Evaluate drive and media */ 00533 disc_state = burn_disc_get_status(drive); 00534 if (disc_state != BURN_DISC_BLANK && 00535 disc_state != BURN_DISC_APPENDABLE) { 00536 if (disc_state == BURN_DISC_FULL) { 00537 fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n"); 00538 if (burn_disc_erasable(drive)) 00539 fprintf(stderr, "HINT: Try --blank_fast\n\n"); 00540 } else if (disc_state == BURN_DISC_EMPTY) 00541 fprintf(stderr,"FATAL: No media detected in drive\n"); 00542 else 00543 fprintf(stderr, 00544 "FATAL: Cannot recognize state of drive and media\n"); 00545 {ret = 0; goto ex;} 00546 } 00547 00548 burn_options = burn_write_opts_new(drive); 00549 burn_write_opts_set_perform_opc(burn_options, 0); 00550 burn_write_opts_set_multi(burn_options, !!multi); 00551 if(simulate_burn) 00552 printf("\n*** Will TRY to SIMULATE burning ***\n\n"); 00553 burn_write_opts_set_simulate(burn_options, simulate_burn); 00554 burn_drive_set_speed(drive, 0, 0); 00555 burn_write_opts_set_underrun_proof(burn_options, 1); 00556 if (burn_write_opts_auto_write_type(burn_options, target_disc, 00557 reasons, 0) == BURN_WRITE_NONE) { 00558 fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n"); 00559 fprintf(stderr, "Reasons given:\n%s\n", reasons); 00560 {ret = 0; goto ex;} 00561 } 00562 burn_set_signal_handling("libburner : ", NULL, 0x30); 00563 00564 printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n"); 00565 start_time = time(0); 00566 burn_disc_write(burn_options, target_disc); 00567 00568 while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) 00569 usleep(100002); 00570 while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { 00571 if (progress.sectors <= 0 || 00572 (progress.sector >= progress.sectors - 1 && 00573 !unpredicted_size) || 00574 (unpredicted_size && progress.sector == last_sector)) 00575 printf( 00576 "Thank you for being patient since %d seconds.", 00577 (int) (time(0) - start_time)); 00578 else if(unpredicted_size) 00579 printf("Track %d : sector %d", progress.track+1, 00580 progress.sector); 00581 else 00582 printf("Track %d : sector %d of %d",progress.track+1, 00583 progress.sector, progress.sectors); 00584 last_sector = progress.sector; 00585 if (progress.track >= 0 && progress.track < source_adr_count) { 00586 int size, free_bytes, ret; 00587 char *status_text; 00588 00589 ret = burn_fifo_inquire_status( 00590 fifo_src[progress.track], &size, &free_bytes, 00591 &status_text); 00592 if (ret >= 0 ) 00593 printf(" [fifo %s, %2d%% fill]", status_text, 00594 (int) (100.0 - 100.0 * 00595 ((double) free_bytes) / 00596 (double) size)); 00597 } 00598 printf("\n"); 00599 sleep(1); 00600 } 00601 printf("\n"); 00602 00603 if (burn_is_aborting(0) > 0) 00604 {ret = -1; goto ex;} 00605 if (multi && current_profile != 0x1a && current_profile != 0x13 && 00606 current_profile != 0x12 && current_profile != 0x43) 00607 /* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */ 00608 printf("NOTE: Media left appendable.\n"); 00609 if (simulate_burn) 00610 printf("\n*** Did TRY to SIMULATE burning ***\n\n"); 00611 ret = 1; 00612 ex:; 00613 /* Dispose objects */ 00614 if (burn_options != NULL) 00615 burn_write_opts_free(burn_options); 00616 for (trackno = 0 ; trackno < source_adr_count; trackno++) { 00617 if (fifo_src[trackno] != NULL) 00618 burn_source_free(fifo_src[trackno]); 00619 if (tracklist[trackno]) 00620 burn_track_free(tracklist[trackno]); 00621 } 00622 if (data_src != NULL) 00623 burn_source_free(data_src); 00624 if (session != NULL) 00625 burn_session_free(session); 00626 if (target_disc != NULL) 00627 burn_disc_free(target_disc); 00628 return ret; 00629 }
int libburner_setup | ( | int | argc, | |
char ** | argv | |||
) |
Converts command line arguments into above setup parameters.
Definition at line 645 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().
00646 { 00647 int i, insuffient_parameters = 0, print_help = 0; 00648 00649 for (i = 1; i < argc; ++i) { 00650 if (!strcmp(argv[i], "--audio")) { 00651 all_tracks_type = BURN_AUDIO; 00652 00653 } else if (!strcmp(argv[i], "--blank_fast")) { 00654 do_blank = 1; 00655 00656 } else if (!strcmp(argv[i], "--blank_full")) { 00657 do_blank = 2; 00658 00659 } else if (!strcmp(argv[i], "--burn_for_real")) { 00660 simulate_burn = 0; 00661 00662 } else if (!strcmp(argv[i], "--drive")) { 00663 ++i; 00664 if (i >= argc) { 00665 fprintf(stderr,"--drive requires an argument\n"); 00666 return 1; 00667 } else if (strcmp(argv[i], "-") == 0) { 00668 drive_adr[0] = 0; 00669 driveno = -1; 00670 } else if (isdigit(argv[i][0])) { 00671 drive_adr[0] = 0; 00672 driveno = atoi(argv[i]); 00673 } else { 00674 if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) { 00675 fprintf(stderr,"--drive address too long (max. %d)\n", 00676 BURN_DRIVE_ADR_LEN-1); 00677 return 2; 00678 } 00679 strcpy(drive_adr, argv[i]); 00680 } 00681 } else if ((!strcmp(argv[i], "--format_overwrite")) || 00682 (!strcmp(argv[i], "--format"))) { 00683 do_blank = 101; 00684 00685 } else if (!strcmp(argv[i], "--multi")) { 00686 do_multi = 1; 00687 00688 } else if (!strcmp(argv[i], "--stdin_size")) { /* obsoleted */ 00689 i++; 00690 00691 } else if (!strcmp(argv[i], "--try_to_simulate")) { 00692 simulate_burn = 1; 00693 00694 } else if (!strcmp(argv[i], "--help")) { 00695 print_help = 1; 00696 00697 } else if (!strncmp(argv[i], "--",2)) { 00698 fprintf(stderr, "Unidentified option: %s\n", argv[i]); 00699 return 7; 00700 } else { 00701 if(strlen(argv[i]) >= 4096) { 00702 fprintf(stderr, "Source address too long (max. %d)\n", 4096-1); 00703 return 5; 00704 } 00705 if(source_adr_count >= 99) { 00706 fprintf(stderr, "Too many tracks (max. 99)\n"); 00707 return 6; 00708 } 00709 strcpy(source_adr[source_adr_count], argv[i]); 00710 source_adr_count++; 00711 } 00712 } 00713 insuffient_parameters = 1; 00714 if (driveno < 0) 00715 insuffient_parameters = 0; 00716 if (source_adr_count > 0) 00717 insuffient_parameters = 0; 00718 if (do_blank) 00719 insuffient_parameters = 0; 00720 if (print_help || insuffient_parameters ) { 00721 printf("Usage: %s\n", argv[0]); 00722 printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n"); 00723 printf(" [--blank_fast|--blank_full|--format] [--try_to_simulate]\n"); 00724 printf(" [--multi] [<one or more imagefiles>|\"-\"]\n"); 00725 printf("Examples\n"); 00726 printf("A bus scan (needs rw-permissions to see a drive):\n"); 00727 printf(" %s --drive -\n",argv[0]); 00728 printf("Burn a file to drive chosen by number, leave appendable:\n"); 00729 printf(" %s --drive 0 --multi my_image_file\n", argv[0]); 00730 printf("Burn a file to drive chosen by persistent address, close:\n"); 00731 printf(" %s --drive /dev/hdc my_image_file\n", argv[0]); 00732 printf("Blank a used CD-RW (is combinable with burning in one run):\n"); 00733 printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]); 00734 printf("Blank a used DVD-RW (is combinable with burning in one run):\n"); 00735 printf(" %s --drive /dev/hdc --blank_full\n",argv[0]); 00736 printf("Format a DVD-RW, BD-RE or BD-R:\n"); 00737 printf(" %s --drive /dev/hdc --format\n", argv[0]); 00738 printf("Burn two audio tracks (to CD only):\n"); 00739 printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n"); 00740 printf(" test/dewav /path/to/track2.wav -o track2.cd\n"); 00741 printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]); 00742 printf("Burn a compressed afio archive on-the-fly:\n"); 00743 printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n"); 00744 printf(" %s --drive /dev/hdc -\n", argv[0]); 00745 printf("To be read from *not mounted* media via: afio -tvZ /dev/hdc\n"); 00746 if (insuffient_parameters) 00747 return 6; 00748 } 00749 return 0; 00750 }
int main | ( | int | argc, | |
char ** | argv | |||
) |
Definition at line 753 of file libburner.c.
References all_tracks_type, burn_abort(), burn_abort_pacifier(), burn_drive_release(), burn_finish(), burn_initialize(), burn_is_aborting(), burn_msgs_set_severities(), burn_set_signal_handling(), do_blank, do_multi, drive_adr, drive_is_grabbed, drive_list, driveno, libburner_aquire_drive(), libburner_blank_disc(), libburner_format(), libburner_payload(), libburner_setup(), simulate_burn, source_adr, and source_adr_count.
00754 { 00755 int ret; 00756 00757 /* A warning to programmers who start their own projekt from here. */ 00758 if (sizeof(off_t) != 8) { 00759 fprintf(stderr, 00760 "\nFATAL: Compile time misconfiguration. off_t is not 64 bit.\n\n"); 00761 exit(39); 00762 } 00763 00764 ret = libburner_setup(argc, argv); 00765 if (ret) 00766 exit(ret); 00767 00768 printf("Initializing libburnia-project.org ...\n"); 00769 if (burn_initialize()) 00770 printf("Done\n"); 00771 else { 00772 printf("FAILED\n"); 00773 fprintf(stderr,"\nFATAL: Failed to initialize.\n"); 00774 exit(33); 00775 } 00776 00777 /* Print messages of severity SORRY or more directly to stderr */ 00778 burn_msgs_set_severities("NEVER", "SORRY", "libburner : "); 00779 00780 /* Activate the synchronous signal handler which eventually will try to 00781 properly shutdown drive and library on aborting events. */ 00782 burn_set_signal_handling("libburner : ", NULL, 0x0); 00783 00784 /** Note: driveno might change its value in this call */ 00785 ret = libburner_aquire_drive(drive_adr, &driveno); 00786 if (ret<=0) { 00787 fprintf(stderr,"\nFATAL: Failed to acquire drive.\n"); 00788 { ret = 34; goto finish_libburn; } 00789 } 00790 if (ret == 2) 00791 { ret = 0; goto release_drive; } 00792 if (do_blank) { 00793 if (do_blank > 100) 00794 ret = libburner_format(drive_list[driveno].drive); 00795 else 00796 ret = libburner_blank_disc(drive_list[driveno].drive, 00797 do_blank == 1); 00798 if (ret<=0) 00799 { ret = 36; goto release_drive; } 00800 } 00801 if (source_adr_count > 0) { 00802 ret = libburner_payload(drive_list[driveno].drive, 00803 source_adr, source_adr_count, 00804 do_multi, simulate_burn, all_tracks_type); 00805 if (ret<=0) 00806 { ret = 38; goto release_drive; } 00807 } 00808 ret = 0; 00809 release_drive:; 00810 if (drive_is_grabbed) 00811 burn_drive_release(drive_list[driveno].drive, 0); 00812 00813 finish_libburn:; 00814 if (burn_is_aborting(0) > 0) { 00815 burn_abort(4400, burn_abort_pacifier, "libburner : "); 00816 fprintf(stderr,"\nlibburner run aborted\n"); 00817 exit(1); 00818 } 00819 /* This app does not bother to know about exact scan state. 00820 Better to accept a memory leak here. We are done anyway. */ 00821 /* burn_drive_info_free(drive_list); */ 00822 burn_finish(); 00823 exit(ret); 00824 }
int all_tracks_type = BURN_MODE1 [static] |
int current_profile = -1 [static] |
A number and a text describing the type of media in acquired drive.
Definition at line 102 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 103 of file libburner.c.
Referenced by libburner_aquire_drive(), and libburner_format().
int do_blank = 0 [static] |
int do_multi = 0 [static] |
char drive_adr[BURN_DRIVE_ADR_LEN] = {""} [static] |
The setup parameters of libburner.
Definition at line 633 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 95 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 99 of file libburner.c.
Referenced by libburner_aquire_by_adr(), libburner_aquire_by_driveno(), 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 91 of file libburner.c.
Referenced by libburner_aquire_by_adr(), libburner_aquire_by_driveno(), libburner_aquire_drive(), libburner_format(), and main().
int driveno = 0 [static] |
int simulate_burn = 0 [static] |
char source_adr[99][4096] [static] |
int source_adr_count = 0 [static] |