libburn-0.4.4/test/libburner.c File Reference

#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>

Include dependency graph for libburner.c:

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 ready for thorough re-usal.
int libburner_format_row (struct burn_drive *drive)
 Persistently changes DVD-RW profile 0014h "Sequential Recording" 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_infodrive_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


Function Documentation

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 121 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().

00122 {
00123     int ret;
00124     char libburn_drive_adr[BURN_DRIVE_ADR_LEN];
00125 
00126     /* Some not-so-harmless drive addresses get blocked in this demo */
00127     if (strncmp(drive_adr, "stdio:/dev/fd/", 14) == 0 ||
00128         strcmp(drive_adr, "stdio:-") == 0) {
00129         fprintf(stderr, "Will not work with pseudo-drive '%s'\n",
00130             drive_adr);
00131         return 0;
00132     }
00133 
00134     /* This tries to resolve links or alternative device files */
00135     ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);  
00136     if (ret<=0) {
00137         fprintf(stderr, "Address does not lead to a CD burner: '%s'\n",
00138                  drive_adr);
00139         return 0;
00140     }
00141     fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr);
00142     ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1);
00143     if (ret <= 0) {
00144         fprintf(stderr,"FAILURE with persistent drive address  '%s'\n",
00145             libburn_drive_adr);
00146     } else {
00147         fprintf(stderr,"Done\n");
00148         drive_is_grabbed = 1;
00149     }
00150     return ret;
00151 }

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().

Parameters:
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.
Returns:
1 success , <= 0 failure

Definition at line 166 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().

00167 {
00168     char adr[BURN_DRIVE_ADR_LEN];
00169     int ret, i;
00170 
00171     printf("Beginning to scan for devices ...\n");
00172     while (!burn_drive_scan(&drive_list, &drive_count))
00173         usleep(100002);
00174     if (drive_count <= 0 && *driveno >= 0) {
00175         printf("FAILED (no drives found)\n");
00176         return 0;
00177     }
00178     printf("Done\n");
00179 
00180     /*
00181     Interactive programs may choose the drive number at this moment.
00182 
00183     drive[0] to drive[drive_count-1] are struct burn_drive_info
00184     as defined in  libburn/libburn.h  . This structure is part of API
00185     and thus will strive for future compatibility on source level.
00186     Have a look at the info offered.
00187     Caution: do not take .location for drive address. Always use
00188         burn_drive_get_adr() or you might become incompatible
00189         in future.
00190     Note: bugs with struct burn_drive_info - if any - will not be
00191         easy to fix. Please report them but also strive for
00192         workarounds on application level.
00193     */
00194     printf("\nOverview of accessible drives (%d found) :\n",
00195         drive_count);
00196     printf("-----------------------------------------------------------------------------\n");
00197     for (i = 0; i < drive_count; i++) {
00198         if (burn_drive_get_adr(&(drive_list[i]), adr) <=0)
00199             strcpy(adr, "-get_adr_failed-");
00200         printf("%d  --drive '%s'  :  '%s'  '%s'\n",
00201             i,adr,drive_list[i].vendor,drive_list[i].product);
00202     }
00203     printf("-----------------------------------------------------------------------------\n\n");
00204 
00205     /*
00206     On multi-drive systems save yourself from sysadmins' revenge.
00207 
00208     Be aware that you hold reserved all available drives at this point.
00209     So either make your choice quick enough not to annoy other system
00210     users, or set free the drives for a while.
00211 
00212     The tested way of setting free all drives is to shutdown the library
00213     and to restart when the choice has been made. The list of selectable
00214     drives should also hold persistent drive addresses as obtained
00215     above by burn_drive_get_adr(). By such an address one may use
00216     burn_drive_scan_and_grab() to finally aquire exactly one drive.
00217 
00218     A not yet tested shortcut should be to call burn_drive_info_free()
00219     and to call either burn_drive_scan() or burn_drive_scan_and_grab()
00220     before accessing any drives again.
00221 
00222     In both cases you have to be aware that the desired drive might get
00223     aquired in the meantime by another user resp. libburn process.
00224     */
00225 
00226     /* We already made our choice via command line. (default is 0)
00227        So we just have to keep our desired drive and drop all others.
00228        No other libburn instance will have a chance to steal our drive.
00229      */
00230     if (*driveno < 0) {
00231         printf("Pseudo-drive \"-\" given : bus scanning done.\n");
00232         return 2; /* the program will end after this */
00233     }
00234     if (drive_count <= *driveno) {
00235         fprintf(stderr,
00236             "Found only %d drives. Number %d not available.\n",
00237             drive_count, *driveno);
00238         return 0; /* the program will end after this */
00239     }
00240 
00241     /* Drop all drives which we do not want to use */
00242     for (i = 0; i < drive_count; i++) {
00243         if (i == *driveno) /* the one drive we want to keep */
00244     continue;
00245         ret = burn_drive_info_forget(&(drive_list[i]),0);
00246         if (ret != 1)
00247             fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n",
00248                 i, ret);
00249         else
00250             printf("Dropped unwanted drive %d\n",i);
00251     }
00252     /* Make the one we want ready for blanking or burning */
00253     ret= burn_drive_grab(drive_list[*driveno].drive, 1);
00254     if (ret != 1)
00255         return 0;
00256     drive_is_grabbed = 1;
00257     return 1;
00258 }

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 99 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().

00100 {
00101     int ret;
00102 
00103     if(drive_adr != NULL && drive_adr[0] != 0)
00104         ret = libburner_aquire_by_adr(drive_adr);
00105     else
00106         ret = libburner_aquire_by_driveno(driveno);
00107     if (ret <= 0)
00108         return ret;
00109     burn_disc_get_profile(drive_list[0].drive, &current_profile,
00110                  current_profile_name);
00111     if (current_profile_name[0])
00112         printf("Detected media type: %s\n", current_profile_name);
00113     return 1;
00114 }

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 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 268 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().

00269 {
00270     enum burn_disc_status disc_state;
00271     struct burn_progress p;
00272     double percent = 1.0;
00273 
00274     disc_state = burn_disc_get_status(drive);
00275     printf(
00276         "Drive media status:  %d  (see  libburn/libburn.h  BURN_DISC_*)\n",
00277         disc_state);
00278     if (current_profile == 0x13) {
00279         ; /* formatted DVD-RW will get blanked to sequential state */
00280     } else if (disc_state == BURN_DISC_BLANK) {
00281         fprintf(stderr,
00282           "IDLE: Blank media detected. Will leave it untouched\n");
00283         return 2;
00284     } else if (disc_state == BURN_DISC_FULL ||
00285            disc_state == BURN_DISC_APPENDABLE) {
00286         ; /* this is what libburner is willing to blank */
00287     } else if (disc_state == BURN_DISC_EMPTY) {
00288         fprintf(stderr,"FATAL: No media detected in drive\n");
00289         return 0;
00290     } else {
00291         fprintf(stderr,
00292             "FATAL: Unsuitable drive and media state\n");
00293         return 0;
00294     }
00295     if(!burn_disc_erasable(drive)) {
00296         fprintf(stderr,
00297             "FATAL : Media is not of erasable type\n");
00298         return 0;
00299     }
00300     printf(
00301           "Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
00302     burn_disc_erase(drive, blank_fast);
00303     sleep(1);
00304     while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
00305         if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
00306             percent = 1.0 + ((double) p.sector+1.0)
00307                      / ((double) p.sectors) * 98.0;
00308         printf("Blanking  ( %.1f%% done )\n", percent);
00309         sleep(1);
00310     }
00311     printf("Done\n");
00312     return 1;
00313 }

int libburner_format_row ( struct burn_drive *  drive  ) 

Persistently changes DVD-RW profile 0014h "Sequential Recording" 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.

Definition at line 322 of file libburner.c.

References burn_disc_format(), burn_disc_get_profile(), burn_drive_get_status(), BURN_DRIVE_IDLE, current_profile, current_profile_name, burn_progress::sector, and burn_progress::sectors.

Referenced by main().

00323 {
00324     struct burn_progress p;
00325     double percent = 1.0;
00326 
00327     if (current_profile == 0x13) {
00328         fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
00329         return 2;
00330     } else if (current_profile != 0x14) {
00331         fprintf(stderr, "FATAL: Can only format DVD-RW\n");
00332         return 0;
00333     }
00334     printf("Beginning to format media.\n");
00335     burn_disc_format(drive, (off_t) 0, 0);
00336 
00337     sleep(1);
00338     while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
00339         if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
00340             percent = 1.0 + ((double) p.sector+1.0)
00341                      / ((double) p.sectors) * 98.0;
00342         printf("Formatting  ( %.1f%% done )\n", percent);
00343         sleep(1);
00344     }
00345     burn_disc_get_profile(drive_list[0].drive, &current_profile,
00346                  current_profile_name);
00347     printf("Media type now: %4.4xh  \"%s\"\n",
00348          current_profile, current_profile_name);
00349     if (current_profile != 0x13) {
00350         fprintf(stderr,
00351           "FATAL: Failed to change media profile to desired value\n");
00352         return 0;
00353     }
00354     return 1;
00355 }

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 373 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().

00376 {
00377     struct burn_source *data_src, *fifo_src[99];
00378     struct burn_disc *target_disc;
00379     struct burn_session *session;
00380     struct burn_write_opts *burn_options;
00381     enum burn_disc_status disc_state;
00382     struct burn_track *track, *tracklist[99];
00383     struct burn_progress progress;
00384     time_t start_time;
00385     int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
00386     int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
00387     off_t fixed_size;
00388     char *adr, reasons[BURN_REASONS_LEN];
00389     struct stat stbuf;
00390 
00391     if (all_tracks_type != BURN_AUDIO) {
00392         all_tracks_type = BURN_MODE1;
00393         /* a padding of 300 kiB helps to avoid the read-ahead bug */
00394         padding = 300*1024;
00395         fifo_chunksize = 2048;
00396         fifo_chunks = 2048; /* 4 MB fifo */
00397     }
00398 
00399     target_disc = burn_disc_create();
00400     session = burn_session_create();
00401     burn_disc_add_session(target_disc, session, BURN_POS_END);
00402 
00403     for (trackno = 0 ; trackno < source_adr_count; trackno++) {
00404       tracklist[trackno] = track = burn_track_create();
00405       burn_track_define_data(track, 0, padding, 1, all_tracks_type);
00406 
00407       /* Open file descriptor to source of track data */
00408       adr = source_adr[trackno];
00409       fixed_size = 0;
00410       if (adr[0] == '-' && adr[1] == 0) {
00411         fd = 0;
00412       } else {
00413         fd = open(adr, O_RDONLY);
00414         if (fd>=0)
00415             if (fstat(fd,&stbuf)!=-1)
00416                 if((stbuf.st_mode&S_IFMT)==S_IFREG)
00417                     fixed_size = stbuf.st_size;
00418       }
00419       if (fixed_size==0)
00420         unpredicted_size = 1;
00421 
00422       /* Convert this filedescriptor into a burn_source object */
00423       data_src = NULL;
00424       if (fd>=0)
00425         data_src = burn_fd_source_new(fd, -1, fixed_size);
00426       if (data_src == NULL) {
00427         fprintf(stderr,
00428                "FATAL: Could not open data source '%s'.\n",adr);
00429         if(errno!=0)
00430             fprintf(stderr,"(Most recent system error: %s )\n",
00431                 strerror(errno));
00432         return 0;
00433       }
00434       /* Install a fifo object on top of that data source object */
00435       fifo_src[trackno] = burn_fifo_source_new(data_src,
00436                     fifo_chunksize, fifo_chunks, 0);
00437       if (fifo_src[trackno] == NULL) {
00438         fprintf(stderr,
00439             "FATAL: Could not create fifo object of 4 MB\n");
00440         return 0;
00441       }
00442 
00443       /* Use the fifo object as data source for the track */
00444       if (burn_track_set_source(track, fifo_src[trackno])
00445                              != BURN_SOURCE_OK) {
00446         fprintf(stderr,
00447                "FATAL: Cannot attach source object to track object\n");
00448         return 0;
00449       }
00450 
00451       burn_session_add_track(session, track, BURN_POS_END);
00452       printf("Track %d : source is '%s'\n", trackno+1, adr);
00453 
00454       /* Give up local reference to the data burn_source object */
00455       burn_source_free(data_src);
00456       
00457         } /* trackno loop end */
00458 
00459     /* Evaluate drive and media */
00460     disc_state = burn_disc_get_status(drive);
00461     if (disc_state != BURN_DISC_BLANK &&
00462         disc_state != BURN_DISC_APPENDABLE) {
00463         if (disc_state == BURN_DISC_FULL) {
00464             fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n");
00465             if (burn_disc_erasable(drive))
00466                 fprintf(stderr, "HINT: Try --blank_fast\n\n");
00467         } else if (disc_state == BURN_DISC_EMPTY) 
00468             fprintf(stderr,"FATAL: No media detected in drive\n");
00469         else
00470             fprintf(stderr,
00471              "FATAL: Cannot recognize state of drive and media\n");
00472         return 0;
00473     }
00474 
00475     burn_options = burn_write_opts_new(drive);
00476     burn_write_opts_set_perform_opc(burn_options, 0);
00477     burn_write_opts_set_multi(burn_options, !!multi);
00478     if(simulate_burn)
00479         printf("\n*** Will TRY to SIMULATE burning ***\n\n");
00480     burn_write_opts_set_simulate(burn_options, simulate_burn);
00481     burn_drive_set_speed(drive, 0, 0);
00482     burn_write_opts_set_underrun_proof(burn_options, 1);
00483     if (burn_write_opts_auto_write_type(burn_options, target_disc,
00484                     reasons, 0) == BURN_WRITE_NONE) {
00485         fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
00486         fprintf(stderr, "Reasons given:\n%s\n", reasons);
00487         return 0;
00488     }
00489 
00490     printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
00491     start_time = time(0);
00492     burn_disc_write(burn_options, target_disc);
00493 
00494     burn_write_opts_free(burn_options);
00495     while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
00496         usleep(100002);
00497     while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
00498         if (progress.sectors <= 0 ||
00499             (progress.sector >= progress.sectors - 1 &&
00500                  !unpredicted_size) ||
00501             (unpredicted_size && progress.sector == last_sector))
00502             printf(
00503                  "Thank you for being patient since %d seconds.",
00504                  (int) (time(0) - start_time));
00505         else if(unpredicted_size)
00506             printf("Track %d : sector %d", progress.track+1,
00507                 progress.sector);
00508         else
00509             printf("Track %d : sector %d of %d",progress.track+1,
00510                 progress.sector, progress.sectors);
00511         last_sector = progress.sector;
00512         if (progress.track >= 0 && progress.track < source_adr_count) {
00513             int size, free_bytes, ret;
00514             char *status_text;
00515     
00516             ret = burn_fifo_inquire_status(
00517                 fifo_src[progress.track], &size, &free_bytes,
00518                 &status_text);
00519             if (ret >= 0 ) 
00520                 printf("  [fifo %s, %2d%% fill]", status_text,
00521                     (int) (100.0 - 100.0 *
00522                         ((double) free_bytes) /
00523                         (double) size));
00524         } 
00525         printf("\n");
00526         sleep(1);
00527     }
00528     printf("\n");
00529 
00530     for (trackno = 0 ; trackno < source_adr_count; trackno++) {
00531         burn_source_free(fifo_src[trackno]);
00532         burn_track_free(tracklist[trackno]);
00533     }
00534     burn_session_free(session);
00535     burn_disc_free(target_disc);
00536     if (multi && current_profile != 0x1a && current_profile != 0x13 &&
00537         current_profile != 0x12) /* not with DVD+RW, DVD-RW, DVD-RAM */
00538         printf("NOTE: Media left appendable.\n");
00539     if (simulate_burn)
00540         printf("\n*** Did TRY to SIMULATE burning ***\n\n");
00541     return 1;
00542 }

int libburner_setup ( int  argc,
char **  argv 
)

Converts command line arguments into above setup parameters.

Definition at line 558 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().

00559 {
00560     int i, insuffient_parameters = 0, print_help = 0;
00561 
00562     for (i = 1; i < argc; ++i) {
00563         if (!strcmp(argv[i], "--audio")) {
00564             all_tracks_type = BURN_AUDIO;
00565 
00566         } else if (!strcmp(argv[i], "--blank_fast")) {
00567             do_blank = 1;
00568 
00569         } else if (!strcmp(argv[i], "--blank_full")) {
00570             do_blank = 2;
00571 
00572         } else if (!strcmp(argv[i], "--burn_for_real")) {
00573             simulate_burn = 0;
00574 
00575         } else if (!strcmp(argv[i], "--drive")) {
00576             ++i;
00577             if (i >= argc) {
00578                 fprintf(stderr,"--drive requires an argument\n");
00579                 return 1;
00580             } else if (strcmp(argv[i], "-") == 0) {
00581                 drive_adr[0] = 0;
00582                 driveno = -1;
00583             } else if (isdigit(argv[i][0])) {
00584                 drive_adr[0] = 0;
00585                 driveno = atoi(argv[i]);
00586             } else {
00587                 if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) {
00588                     fprintf(stderr,"--drive address too long (max. %d)\n",
00589                             BURN_DRIVE_ADR_LEN-1);
00590                     return 2;
00591                 }
00592                 strcpy(drive_adr, argv[i]);
00593             }
00594         } else if (!strcmp(argv[i], "--format_overwrite")) {
00595             do_blank = 101;
00596 
00597         } else if (!strcmp(argv[i], "--multi")) {
00598         do_multi = 1;
00599 
00600     } else if (!strcmp(argv[i], "--stdin_size")) { /* obsoleted */
00601         i++;
00602 
00603         } else if (!strcmp(argv[i], "--try_to_simulate")) {
00604             simulate_burn = 1;
00605 
00606         } else if (!strcmp(argv[i], "--help")) {
00607             print_help = 1;
00608 
00609         } else if (!strncmp(argv[i], "--",2)) {
00610             fprintf(stderr, "Unidentified option: %s\n", argv[i]);
00611             return 7;
00612         } else {
00613             if(strlen(argv[i]) >= 4096) {
00614                 fprintf(stderr, "Source address too long (max. %d)\n", 4096-1);
00615                 return 5;
00616             }
00617             if(source_adr_count >= 99) {
00618                 fprintf(stderr, "Too many tracks (max. 99)\n");
00619                 return 6;
00620             }
00621             strcpy(source_adr[source_adr_count], argv[i]);
00622             source_adr_count++;
00623         }
00624     }
00625     insuffient_parameters = 1;
00626     if (driveno < 0)
00627         insuffient_parameters = 0;
00628     if (source_adr_count > 0)
00629         insuffient_parameters = 0; 
00630     if (do_blank)
00631         insuffient_parameters = 0;
00632     if (print_help || insuffient_parameters ) {
00633         printf("Usage: %s\n", argv[0]);
00634         printf("       [--drive <address>|<driveno>|\"-\"]  [--audio]\n");
00635         printf("       [--blank_fast|--blank_full|--format_overwrite]\n");
00636     printf("       [--try_to_simulate]\n");
00637         printf("       [--multi]  [<one or more imagefiles>|\"-\"]\n");
00638         printf("Examples\n");
00639         printf("A bus scan (needs rw-permissions to see a drive):\n");
00640         printf("  %s --drive -\n",argv[0]);
00641         printf("Burn a file to drive chosen by number, leave appendable:\n");
00642         printf("  %s --drive 0 --multi my_image_file\n", argv[0]);
00643         printf("Burn a file to drive chosen by persistent address, close:\n");
00644         printf("  %s --drive /dev/hdc my_image_file\n", argv[0]);
00645         printf("Blank a used CD-RW (is combinable with burning in one run):\n");
00646         printf("  %s --drive /dev/hdc --blank_fast\n",argv[0]);
00647         printf("Blank a used DVD-RW (is combinable with burning in one run):\n");
00648         printf("  %s --drive /dev/hdc --blank_full\n",argv[0]);
00649         printf("Format a DVD-RW to avoid need for blanking before re-use:\n");
00650         printf("  %s --drive /dev/hdc --format_overwrite\n", argv[0]);
00651         printf("Burn two audio tracks (to CD only):\n");
00652         printf("  lame --decode -t /path/to/track1.mp3 track1.cd\n");
00653         printf("  test/dewav /path/to/track2.wav -o track2.cd\n");
00654         printf("  %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]);
00655         printf("Burn a compressed afio archive on-the-fly:\n");
00656         printf("  ( cd my_directory ; find . -print | afio -oZ - ) | \\\n");
00657         printf("  %s --drive /dev/hdc -\n", argv[0]);
00658         printf("To be read from *not mounted* media via: afio -tvZ /dev/hdc\n");
00659         if (insuffient_parameters)
00660             return 6;
00661     }
00662     return 0;
00663 }

int main ( int  argc,
char **  argv 
)

Note: driveno might change its value in this call

Definition at line 666 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_row(), libburner_payload(), libburner_setup(), simulate_burn, source_adr, and source_adr_count.

00667 {
00668     int ret;
00669 
00670     ret = libburner_setup(argc, argv);
00671     if (ret)
00672         exit(ret);
00673 
00674     printf("Initializing libburnia-project.org ...\n");
00675     if (burn_initialize())
00676         printf("Done\n");
00677     else {
00678         printf("FAILED\n");
00679         fprintf(stderr,"\nFATAL: Failed to initialize.\n");
00680         exit(33);
00681     }
00682 
00683     /* Print messages of severity SORRY or more directly to stderr */
00684     burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
00685 
00686     /* Activate the default signal handler which eventually will try to
00687        properly shutdown drive and library on aborting events. */
00688     burn_set_signal_handling("libburner : ", NULL, 0);
00689 
00690     /** Note: driveno might change its value in this call */
00691     ret = libburner_aquire_drive(drive_adr, &driveno);
00692     if (ret<=0) {
00693         fprintf(stderr,"\nFATAL: Failed to aquire drive.\n");
00694         { ret = 34; goto finish_libburn; }
00695     }
00696     if (ret == 2)
00697         { ret = 0; goto release_drive; }
00698     if (do_blank) {
00699         if (do_blank > 100)
00700             ret = libburner_format_row(drive_list[driveno].drive);
00701         else
00702             ret = libburner_blank_disc(drive_list[driveno].drive,
00703                             do_blank == 1);
00704         if (ret<=0)
00705             { ret = 36; goto release_drive; }
00706     }
00707     if (source_adr_count > 0) {
00708         ret = libburner_payload(drive_list[driveno].drive,
00709                 source_adr, source_adr_count,
00710                 do_multi, simulate_burn, all_tracks_type);
00711         if (ret<=0)
00712             { ret = 38; goto release_drive; }
00713     }
00714     ret = 0;
00715 release_drive:;
00716     if (drive_is_grabbed)
00717         burn_drive_release(drive_list[driveno].drive, 0);
00718 
00719 finish_libburn:;
00720     /* This app does not bother to know about exact scan state. 
00721        Better to accept a memory leak here. We are done anyway. */
00722     /* burn_drive_info_free(drive_list); */
00723 
00724     burn_finish();
00725     exit(ret);
00726 }


Variable Documentation

int all_tracks_type = BURN_MODE1 [static]

Definition at line 553 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 76 of file libburner.c.

Referenced by libburner_aquire_drive(), libburner_blank_disc(), libburner_format_row(), and libburner_payload().

char current_profile_name[80] = {""} [static]

Definition at line 77 of file libburner.c.

Referenced by libburner_aquire_drive(), and libburner_format_row().

int do_blank = 0 [static]

Definition at line 548 of file libburner.c.

Referenced by libburner_setup(), and main().

int do_multi = 0 [static]

Definition at line 551 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 546 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 69 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 73 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 a DVD-RW, can burn to CD-R, CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RAM or DVD-RW. Not supported yet: DVD-R/DL, BD.

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) libburner_format_row() With the aquired drive you can burn to CD or DVD 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 65 of file libburner.c.

int driveno = 0 [static]

Definition at line 547 of file libburner.c.

Referenced by libburner_setup(), and main().

int simulate_burn = 0 [static]

Definition at line 552 of file libburner.c.

Referenced by libburner_setup(), and main().

char source_adr[99][4096] [static]

Definition at line 549 of file libburner.c.

Referenced by libburner_setup(), and main().

int source_adr_count = 0 [static]

Definition at line 550 of file libburner.c.

Referenced by libburner_setup(), and main().


Generated on Sat May 10 11:29:55 2008 for libburn by  doxygen 1.5.5