|
libisoburn 0.5.6
|
00001 00002 /* 00003 cc -g -c isoburn.c 00004 */ 00005 00006 /* 00007 Class core of libisoburn. 00008 00009 Copyright 2007 - 2010 Vreixo Formoso Lopes <metalpain2002@yahoo.es> 00010 Thomas Schmitt <scdbackup@gmx.net> 00011 00012 Provided under GPL version 2 or later. 00013 */ 00014 00015 /* ( derived from stub generated by CgeN on Sat, 01 Sep 2007 12:04:36 GMT ) */ 00016 00017 #include <sys/types.h> 00018 #include <stdlib.h> 00019 #include <stdio.h> 00020 #include <string.h> 00021 #include <errno.h> 00022 #include <unistd.h> 00023 00024 #ifndef Xorriso_standalonE 00025 00026 #include <libburn/libburn.h> 00027 00028 #include <libisofs/libisofs.h> 00029 00030 #else /* ! Xorriso_standalonE */ 00031 00032 #include "../libisofs/libisofs.h" 00033 #include "../libburn/libburn.h" 00034 00035 #endif /* Xorriso_standalonE */ 00036 00037 00038 #include "libisoburn.h" 00039 00040 #include "isoburn.h" 00041 00042 00043 /* Default values for application provided msgs_submit methods. 00044 To be attached to newly aquired drives. 00045 */ 00046 int (*libisoburn_default_msgs_submit) 00047 (void *handle, int error_code, char msg_text[], 00048 int os_errno, char severity[], int flag)= NULL; 00049 void *libisoburn_default_msgs_submit_handle= NULL; 00050 int libisoburn_default_msgs_submit_flag= 0; 00051 00052 00053 /* ----------------------- isoburn_toc_entry ---------------------- */ 00054 00055 00056 int isoburn_toc_entry_new(struct isoburn_toc_entry **objpt, 00057 struct isoburn_toc_entry *boss, int flag) 00058 { 00059 struct isoburn_toc_entry *o, *s; 00060 00061 *objpt= o= (struct isoburn_toc_entry *) 00062 malloc(sizeof(struct isoburn_toc_entry)); 00063 if(o==NULL) { 00064 isoburn_msgs_submit(NULL, 0x00060000, 00065 "Cannot allocate memory for isoburn toc entry", 00066 0, "FATAL", 0); 00067 return(-1); 00068 } 00069 o->session= 0; 00070 o->track_no= 0; 00071 o->start_lba= -1; 00072 o->track_blocks= 0; 00073 o->volid= NULL; 00074 o->next= NULL; 00075 if(boss!=NULL) { 00076 for(s= boss; s->next!=NULL; s= s->next); 00077 s->next= o; 00078 } 00079 return(1); 00080 } 00081 00082 00083 /* @param flag bit0= delete all subordinates too 00084 */ 00085 int isoburn_toc_entry_destroy(struct isoburn_toc_entry **o, int flag) 00086 { 00087 if(*o==NULL) 00088 return(0); 00089 if(flag&1) 00090 isoburn_toc_entry_destroy(&((*o)->next), flag); 00091 if((*o)->volid != NULL) 00092 free((*o)->volid); 00093 free((char *) (*o)); 00094 *o= NULL; 00095 return(1); 00096 } 00097 00098 00099 /* --------------------- end isoburn_toc_entry -------------------- */ 00100 00101 /* -------------------------- isoburn ----------------------- */ 00102 00103 00104 /* The global list of isoburn objects. Usually there is only one. 00105 >>> we are not ready for multiple control threads yet. See >>> mutex . 00106 Multiple burns under one control thread should work. 00107 */ 00108 struct isoburn *isoburn_list_start= NULL; 00109 00110 00111 int isoburn_new(struct isoburn **objpt, int flag) 00112 { 00113 struct isoburn *o; 00114 int i, ret; 00115 00116 *objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn)); 00117 if(o==NULL) { 00118 isoburn_msgs_submit(NULL, 0x00060000, 00119 "Cannot allocate memory for isoburn control object", 00120 0, "FATAL", 0); 00121 return(-1); 00122 } 00123 00124 o->drive= NULL; 00125 o->emulation_mode= 0; 00126 o->fabricated_msc1= -1; 00127 o->fabricated_msc2= -1; 00128 o->zero_nwa= Libisoburn_overwriteable_starT; 00129 o->min_start_byte= o->zero_nwa * 2048; 00130 o->nwa= o->zero_nwa; 00131 o->truncate= 0; 00132 o->iso_source= NULL; 00133 o->fabricated_disc_status= BURN_DISC_UNREADY; 00134 o->toc= NULL; 00135 o->wrote_well= -1; 00136 for(i=0;i<Libisoburn_target_head_sizE;i++) 00137 o->target_iso_head[i]= 0; 00138 o->image= NULL; 00139 o->iso_data_source= NULL; 00140 o->read_pacifier= NULL; 00141 o->read_pacifier_handle= NULL; 00142 o->msgs_submit= NULL; 00143 o->msgs_submit_handle= NULL; 00144 o->msgs_submit_flag= 0; 00145 o->prev= NULL; 00146 o->next= NULL; 00147 ret= iso_image_new("ISOIMAGE", &o->image); 00148 if(ret<0) { 00149 isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0); 00150 goto failed; 00151 } 00152 isoburn_link(o, isoburn_list_start, 1); 00153 return(1); 00154 failed:; 00155 isoburn_destroy(objpt, 0); 00156 return(-1); 00157 } 00158 00159 00160 int isoburn_destroy(struct isoburn **objpt, int flag) 00161 { 00162 struct isoburn *o; 00163 00164 o= *objpt; 00165 if(o==NULL) 00166 return(0); 00167 00168 /* >>> mutex */ 00169 00170 if(o==isoburn_list_start) 00171 isoburn_list_start= o->next; 00172 if(o->prev!=NULL) 00173 o->prev->next= o->next; 00174 if(o->next!=NULL) 00175 o->next->prev= o->prev; 00176 00177 /* >>> end mutex */ 00178 00179 if(o->image!=NULL) 00180 iso_image_unref(o->image); 00181 if(o->toc!=NULL) 00182 isoburn_toc_entry_destroy(&(o->toc), 1); /* all */ 00183 if(o->iso_source!=NULL) 00184 burn_source_free(o->iso_source); 00185 if(o->iso_data_source!=NULL) 00186 iso_data_source_unref(o->iso_data_source); 00187 free((char *) o); 00188 *objpt= NULL; 00189 return(1); 00190 } 00191 00192 00193 int isoburn_destroy_all(struct isoburn **objpt, int flag) 00194 { 00195 struct isoburn *o,*n; 00196 00197 o= *objpt; 00198 if(o==NULL) 00199 return(0); 00200 for(;o->prev!=NULL;o= o->prev); 00201 for(;o!=NULL;o= n) { 00202 n= o->next; 00203 isoburn_destroy(&o,0); 00204 } 00205 *objpt= NULL; 00206 return(1); 00207 } 00208 00209 00210 int isoburn_get_target_image(struct isoburn *o, IsoImage **pt, int flag) 00211 { 00212 *pt= o->image; 00213 return(1); 00214 } 00215 00216 00217 int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag) 00218 { 00219 *pt= o->prev; 00220 return(1); 00221 } 00222 00223 00224 int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag) 00225 { 00226 *pt= o->next; 00227 return(1); 00228 } 00229 00230 00231 int isoburn_link(struct isoburn *o, struct isoburn *link, int flag) 00232 /* 00233 bit0= insert as link->prev rather than as link->next 00234 */ 00235 { 00236 00237 /* >>> mutex */ 00238 00239 if(isoburn_list_start==NULL || 00240 (isoburn_list_start==link && (flag&1))) 00241 isoburn_list_start= o; 00242 if(o->prev!=NULL) 00243 o->prev->next= o->next; 00244 if(o->next!=NULL) 00245 o->next->prev= o->prev; 00246 o->prev= o->next= NULL; 00247 if(link==NULL) 00248 return(1); 00249 if(flag&1) { 00250 o->next= link; 00251 o->prev= link->prev; 00252 if(o->prev!=NULL) 00253 o->prev->next= o; 00254 link->prev= o; 00255 } else { 00256 o->prev= link; 00257 o->next= link->next; 00258 if(o->next!=NULL) 00259 o->next->prev= o; 00260 link->next= o; 00261 } 00262 00263 /* >>> end mutex */ 00264 00265 return(1); 00266 } 00267 00268 00269 int isoburn_count(struct isoburn *o, int flag) 00270 /* flag: bit1= count from start of list */ 00271 { 00272 int counter= 0; 00273 00274 if(flag&2) 00275 for(;o->prev!=NULL;o= o->prev); 00276 for(;o!=NULL;o= o->next) 00277 counter++; 00278 return(counter); 00279 } 00280 00281 00282 int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag) 00283 /* flag: bit0= fetch first (idx<0) or last (idx>0) item in list 00284 bit1= address from start of list */ 00285 { 00286 int i,abs_idx; 00287 struct isoburn *npt; 00288 00289 if(flag&2) 00290 for(;o->prev!=NULL;o= o->prev); 00291 abs_idx= (idx>0?idx:-idx); 00292 *pt= o; 00293 for(i= 0;(i<abs_idx || (flag&1)) && *pt!=NULL;i++) { 00294 if(idx>0) 00295 npt= o->next; 00296 else 00297 npt= o->prev; 00298 if(npt==NULL && (flag&1)) 00299 break; 00300 *pt= npt; 00301 } 00302 return(*pt!=NULL); 00303 } 00304 00305 00306 int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag) 00307 { 00308 struct isoburn *o; 00309 00310 *pt= NULL; 00311 for(o= isoburn_list_start;o!=NULL;o= o->next) 00312 if(o->drive==d) { 00313 *pt= o; 00314 return(1); 00315 } 00316 return(0); 00317 } 00318 00319 00320 int isoburn_msgs_submit(struct isoburn *o, int error_code, char msg_text[], 00321 int os_errno, char severity[], int flag) 00322 { 00323 int ret, use_drive_method= 0; 00324 00325 if(o!=NULL) 00326 if(o->msgs_submit!=NULL) 00327 use_drive_method= 1; 00328 if(use_drive_method) { 00329 ret= o->msgs_submit(o->msgs_submit_handle, error_code, msg_text, os_errno, 00330 severity, o->msgs_submit_flag); 00331 return(ret); 00332 } 00333 if(libisoburn_default_msgs_submit != NULL) { 00334 ret= libisoburn_default_msgs_submit(libisoburn_default_msgs_submit_handle, 00335 error_code, msg_text, os_errno, severity, 00336 libisoburn_default_msgs_submit_flag); 00337 return(ret); 00338 } 00339 /* Fallback: use message queue of libburn */ 00340 burn_msgs_submit(error_code, msg_text, os_errno, severity, NULL); 00341 return(1); 00342 } 00343 00344 00345 /* @param flag bit0= modifying rather than growing 00346 bit1= prepare for early release of input drive: 00347 wait until input and then disable image data source 00348 */ 00349 static 00350 int isoburn_prepare_disc_aux(struct burn_drive *in_d, struct burn_drive *out_d, 00351 struct burn_disc **disc, 00352 struct isoburn_imgen_opts *opts, int flag) 00353 { 00354 struct burn_source *wsrc; 00355 struct burn_session *session; 00356 struct burn_track *track; 00357 struct isoburn *in_o, *out_o; 00358 IsoWriteOpts *wopts= NULL; 00359 enum burn_disc_status state; 00360 int ret, fifo_chunks, lba, nwa, i, new_img, early_indev_release; 00361 uint32_t data_start= -1; 00362 size_t buffer_size= 0, buffer_free= 0; 00363 char msg[160]; 00364 00365 new_img= flag&1; 00366 early_indev_release= flag&2; 00367 00368 ret= isoburn_find_emulator(&in_o, in_d, 0); 00369 if(ret<0 || in_o==NULL) 00370 {ret= -1; goto ex;} 00371 ret= isoburn_find_emulator(&out_o, out_d, 0); 00372 if(ret<0 || out_o==NULL) 00373 {ret= -1; goto ex;} 00374 /* early end will be registered as failure */ 00375 in_o->wrote_well= out_o->wrote_well= 0; 00376 00377 if(new_img && early_indev_release) { 00378 isoburn_msgs_submit(in_o, 0x00060000, 00379 "Programming error: Wrong session setup: new_img && early_indev_release", 00380 0, "FATAL", 0); 00381 {ret= -4; goto ex;} 00382 } 00383 00384 state = isoburn_disc_get_status(in_d); 00385 if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE && 00386 state != BURN_DISC_FULL) { 00387 isoburn_msgs_submit(in_o, 0x00060000, "Unsuitable source media state", 00388 0, "FAILURE", 0); 00389 {ret= -2; goto ex;} 00390 } 00391 state = isoburn_disc_get_status(out_d); 00392 if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { 00393 isoburn_msgs_submit(out_o, 0x00060000, "Unsuitable target media state", 00394 0, "FAILURE", 0); 00395 {ret= -2; goto ex;} 00396 } 00397 00398 fifo_chunks= 32; 00399 if(opts->fifo_size >= 64*1024 && opts->fifo_size <= 1024.0 * 1024.0 * 1024.0){ 00400 fifo_chunks= opts->fifo_size/2048; 00401 if(fifo_chunks*2048 < opts->fifo_size) 00402 fifo_chunks++; 00403 } 00404 00405 ret = iso_write_opts_new(&wopts, 0); 00406 if (ret < 0) { 00407 isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0); 00408 goto ex; 00409 } 00410 iso_write_opts_set_iso_level(wopts, opts->level); 00411 iso_write_opts_set_rockridge(wopts, opts->rockridge); 00412 iso_write_opts_set_joliet(wopts, opts->joliet); 00413 iso_write_opts_set_iso1999(wopts, opts->iso1999); 00414 00415 /* <<< #ifdef shall be removed when libisofs-0.6.20 is released */ 00416 #ifdef Libisofs_hardlink_prooF 00417 00418 iso_write_opts_set_hardlinks(wopts, opts->hardlinks); 00419 if(opts->hardlinks) 00420 iso_write_opts_set_rrip_1_10_px_ino(wopts, 1); 00421 00422 #endif 00423 00424 iso_write_opts_set_aaip(wopts, opts->aaip); 00425 iso_write_opts_set_omit_version_numbers(wopts, opts->omit_version_numbers); 00426 iso_write_opts_set_allow_deep_paths(wopts, opts->allow_deep_paths); 00427 iso_write_opts_set_allow_longer_paths(wopts, opts->allow_longer_paths); 00428 iso_write_opts_set_max_37_char_filenames(wopts, opts->max_37_char_filenames); 00429 iso_write_opts_set_no_force_dots(wopts, opts->no_force_dots); 00430 iso_write_opts_set_allow_lowercase(wopts, opts->allow_lowercase); 00431 iso_write_opts_set_allow_full_ascii(wopts, opts->allow_full_ascii); 00432 iso_write_opts_set_relaxed_vol_atts(wopts, 1); 00433 iso_write_opts_set_joliet_longer_paths(wopts, opts->joliet_longer_paths); 00434 iso_write_opts_set_always_gmt(wopts, opts->always_gmt); 00435 iso_write_opts_set_rrip_version_1_10(wopts, opts->rrip_version_1_10); 00436 iso_write_opts_set_dir_rec_mtime(wopts, opts->dir_rec_mtime); 00437 iso_write_opts_set_aaip_susp_1_10(wopts, opts->aaip_susp_1_10); 00438 iso_write_opts_set_sort_files(wopts, opts->sort_files); 00439 iso_write_opts_set_record_md5(wopts, opts->session_md5, opts->file_md5 & 3); 00440 if(opts->scdbackup_tag_name[0] && opts->scdbackup_tag_time[0]) 00441 iso_write_opts_set_scdbackup_tag(wopts, opts->scdbackup_tag_name, 00442 opts->scdbackup_tag_time, 00443 opts->scdbackup_tag_written); 00444 iso_write_opts_set_replace_mode(wopts, opts->replace_dir_mode, 00445 opts->replace_file_mode, opts->replace_uid, opts->replace_gid); 00446 iso_write_opts_set_default_dir_mode(wopts, opts->dir_mode); 00447 iso_write_opts_set_default_file_mode(wopts, opts->file_mode); 00448 iso_write_opts_set_default_uid(wopts, opts->uid); 00449 iso_write_opts_set_default_gid(wopts, opts->gid); 00450 iso_write_opts_set_output_charset(wopts, opts->output_charset); 00451 iso_write_opts_set_fifo_size(wopts, fifo_chunks); 00452 ret = iso_write_opts_set_system_area(wopts, opts->system_area_data, 00453 opts->system_area_options, 0); 00454 if (ret < 0) { 00455 isoburn_report_iso_error(ret, "Cannot set content of System Area", 00456 0, "FAILURE", 0); 00457 {ret= -1; goto ex;} 00458 } 00459 iso_write_opts_set_pvd_times(wopts, 00460 opts->vol_creation_time, opts->vol_modification_time, 00461 opts->vol_expiration_time, opts->vol_effective_time, 00462 opts->vol_uuid); 00463 00464 ret = isoburn_disc_track_lba_nwa(out_d, NULL, 0, &lba, &nwa); 00465 opts->effective_lba= nwa; 00466 ret= isoburn_get_msc2(out_o, NULL, &nwa, 0); 00467 if (ret != 1) { 00468 isoburn_msgs_submit(out_o, 0x00060000, 00469 "Cannot determine next writeable address", 0, "FAILURE", 0); 00470 {ret= -3; goto ex;} 00471 } 00472 iso_write_opts_set_ms_block(wopts, nwa); 00473 iso_write_opts_set_appendable(wopts, !new_img); 00474 iso_write_opts_set_overwrite_buf(wopts, 00475 nwa>0 ? out_o->target_iso_head : NULL); 00476 00477 ret = iso_image_create_burn_source(in_o->image, wopts, &wsrc); 00478 if (ret < 0) { 00479 isoburn_report_iso_error(ret, "Cannot create burn source", 0, "FAILURE", 0); 00480 {ret= -1; goto ex;} 00481 } 00482 if (early_indev_release) { 00483 for(i= 0; i<300; i++) { 00484 00485 /* <<< ??? */ 00486 if((i%30) == 0) { 00487 sprintf(msg, "Waiting for data in fifo since %d seconds", i/30); 00488 isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0); 00489 } 00490 00491 usleep(100000); 00492 ret= iso_ring_buffer_get_status(wsrc, &buffer_size, &buffer_free); 00493 if(ret >0 && buffer_size != buffer_free) 00494 break; 00495 } 00496 00497 /* <<< ??? */ 00498 sprintf(msg, 00499 "After %.1f seconds: %d bytes of output available (fifo state=%d)", 00500 ((double) i+1) / 10.0, (int) (buffer_size - buffer_free), ret); 00501 isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0); 00502 00503 if(in_o->iso_data_source!=NULL) 00504 isoburn_data_source_shutdown(in_o->iso_data_source, 0); 00505 } 00506 00507 ret= iso_write_opts_get_data_start(wopts, &data_start, 0); 00508 opts->data_start_lba= -1; 00509 if(ret > 0 && data_start <= 0x7FFFFFFF) 00510 opts->data_start_lba= data_start; 00511 00512 /* TODO check return values for failure. propertly clean-up on error */ 00513 00514 out_o->iso_source= wsrc; 00515 00516 *disc = burn_disc_create(); 00517 session = burn_session_create(); 00518 burn_disc_add_session(*disc, session, BURN_POS_END); 00519 track = burn_track_create(); 00520 burn_track_set_source(track, out_o->iso_source); 00521 burn_session_add_track(session, track, BURN_POS_END); 00522 00523 /* give up local references */ 00524 burn_track_free(track); 00525 burn_session_free(session); 00526 00527 in_o->wrote_well= out_o->wrote_well= -1; /* neutral */ 00528 ret= 1; 00529 ex: 00530 if(wopts!=NULL) 00531 {iso_write_opts_free(wopts); wopts= NULL;} 00532 return ret; 00533 } 00534 00535 00536 int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc, 00537 struct isoburn_imgen_opts *opts) 00538 { 00539 return isoburn_prepare_disc_aux(d, d, disc, opts, 0); 00540 } 00541 00542 00543 int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc, 00544 struct isoburn_imgen_opts *opts, 00545 struct burn_drive *out_drive) 00546 { 00547 int ret; 00548 00549 ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 1); 00550 if (ret<=0) 00551 return ret; 00552 return 1; 00553 } 00554 00555 00556 /* API since 0.2.2 */ 00557 int isoburn_prepare_blind_grow(struct burn_drive *d, struct burn_disc **disc, 00558 struct isoburn_imgen_opts *opts, 00559 struct burn_drive *out_drive, int nwa) 00560 { 00561 int ret; 00562 struct isoburn *o= NULL; 00563 00564 ret= isoburn_find_emulator(&o, out_drive, 0); 00565 if(ret<0 || o==NULL) 00566 return(-1); 00567 if(nwa >= 0) 00568 o->fabricated_msc2= nwa; 00569 if(o->nwa == o->zero_nwa) 00570 o->nwa= o->zero_nwa= 0; 00571 else 00572 o->zero_nwa= 0; 00573 ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 2); 00574 if (ret<=0) 00575 return ret; 00576 return(1); 00577 } 00578 00579 00580 /* API @since 0.1.0 00581 @param flag bit0= this is a regular end, not an abort 00582 give up source reference 00583 */ 00584 int isoburn_cancel_prepared_write(struct burn_drive *d, 00585 struct burn_drive *output_drive, int flag) 00586 { 00587 int ret; 00588 struct isoburn *o= NULL; 00589 00590 if(output_drive!=NULL) { 00591 ret= isoburn_find_emulator(&o, output_drive, 0); 00592 if(ret<0 || o==NULL) 00593 o= NULL; 00594 else if(o->iso_source==NULL) 00595 o= NULL; 00596 } 00597 if(o==NULL) { 00598 ret= isoburn_find_emulator(&o, d, 0); 00599 if(ret<0) 00600 return(-1); 00601 if(o==NULL) 00602 return(0); 00603 if(o->iso_source==NULL) 00604 return(0); 00605 } 00606 if(o->iso_source->read!=NULL) 00607 return(0); 00608 if(o->iso_source->version<1) 00609 return(0); 00610 o->iso_source->cancel(o->iso_source); 00611 burn_source_free(o->iso_source); 00612 o->iso_source= NULL; 00613 return(1); 00614 } 00615 00616 00617 /* API @since 0.1.0 */ 00618 int isoburn_sync_after_write(struct burn_drive *d, 00619 struct burn_drive *output_drive, int flag) 00620 { 00621 return isoburn_cancel_prepared_write(d, output_drive, 1); 00622 } 00623 00624 00625 void isoburn_version(int *major, int *minor, int *micro) 00626 { 00627 *major= isoburn_header_version_major; 00628 *minor= isoburn_header_version_minor; 00629 *micro= isoburn_header_version_micro; 00630 00631 /* No more: values from version.h generated from version.h.in and 00632 macro values defined in configure.ac 00633 00634 *major = ISOBURN_MAJOR_VERSION; 00635 *minor = ISOBURN_MINOR_VERSION; 00636 *micro = ISOBURN_MICRO_VERSION; 00637 */ 00638 } 00639 00640 00641 int isoburn_is_compatible(int major, int minor, int micro, int flag) 00642 { 00643 int own_major, own_minor, own_micro; 00644 00645 isoburn_version(&own_major, &own_minor, &own_micro); 00646 return(own_major > major || 00647 (own_major == major && (own_minor > minor || 00648 (own_minor == minor && own_micro >= micro)))); 00649 } 00650 00651 00652 /* ----------------------------------------------------------------------- */ 00653 /* 00654 Options for image reading. 00655 */ 00656 /* ----------------------------------------------------------------------- */ 00657 00658 00659 int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag) 00660 { 00661 struct isoburn_read_opts *o; 00662 00663 o= (*new_o)= calloc(1, sizeof(struct isoburn_read_opts)); 00664 if(o==NULL) { 00665 isoburn_msgs_submit(NULL, 0x00060000, 00666 "Cannot allocate memory for read options", 0, "FATAL", 0); 00667 return(-1); 00668 } 00669 o->norock= 0; 00670 o->nojoliet= 0; 00671 o->noiso1999= 1; 00672 o->noaaip= 1; 00673 o->noacl= 1; 00674 o->noea= 1; 00675 o->noino= 1; 00676 o->nomd5= 1; 00677 o->preferjoliet= 0; 00678 o->uid= geteuid(); 00679 o->gid= getegid(); 00680 o->mode= 0444; 00681 o->dirmode= 0555; 00682 o->input_charset= NULL; 00683 o->hasRR= 0; 00684 o->hasJoliet= 0; 00685 o->hasIso1999= 0; 00686 o->hasElTorito= 0; 00687 o->size= 0; 00688 o->pretend_blank= 1; 00689 return(1); 00690 } 00691 00692 00693 int isoburn_ropt_destroy(struct isoburn_read_opts **o, int flag) 00694 { 00695 if(*o==NULL) 00696 return(0); 00697 free(*o); 00698 *o= NULL; 00699 return(1); 00700 } 00701 00702 00703 int isoburn_ropt_set_extensions(struct isoburn_read_opts *o, int ext) 00704 { 00705 o->norock= !!(ext&1); 00706 o->nojoliet= !!(ext&2); 00707 o->noiso1999= !!(ext&4); 00708 o->preferjoliet= !!(ext&8); 00709 o->pretend_blank= !!(ext&16); 00710 o->noaaip= !!(ext & 32); 00711 o->noacl= !!(ext & 64); 00712 o->noea= !!(ext & 128); 00713 o->noino= !!(ext & 256); 00714 o->nomd5= !!(ext & 512); 00715 return(1); 00716 } 00717 00718 00719 int isoburn_ropt_get_extensions(struct isoburn_read_opts *o, int *ext) 00720 { 00721 *ext= (!!o->norock) | ((!!o->nojoliet)<<1) | ((!!o->noiso1999)<<2) | 00722 ((!!o->preferjoliet)<<3) | ((!!o->pretend_blank)<<4) | 00723 ((!!o->noaaip) << 5) | ((!!o->noacl) << 6) | ((!!o->noea) << 7) | 00724 ((!!o->noino) << 8) | ((!!o->nomd5) << 9); 00725 return(1); 00726 } 00727 00728 00729 int isoburn_ropt_set_default_perms(struct isoburn_read_opts *o, 00730 uid_t uid, gid_t gid, mode_t mode) 00731 { 00732 mode_t dirmode; 00733 00734 o->uid= uid; 00735 o->gid= gid; 00736 o->mode= mode; 00737 dirmode= mode; 00738 if(dirmode & S_IRUSR) 00739 dirmode|= S_IXUSR; 00740 if(dirmode & S_IRGRP) 00741 dirmode|= S_IXGRP; 00742 if(dirmode & S_IROTH) 00743 dirmode|= S_IXOTH; 00744 o->dirmode= dirmode; 00745 return(1); 00746 } 00747 00748 00749 int isoburn_ropt_get_default_perms(struct isoburn_read_opts *o, 00750 uid_t *uid, gid_t *gid, mode_t *mode) 00751 { 00752 *uid= o->uid; 00753 *gid= o->gid; 00754 *mode= o->mode; 00755 return(1); 00756 } 00757 00758 00759 int isoburn_ropt_set_default_dirperms(struct isoburn_read_opts *o, 00760 mode_t mode) 00761 { 00762 o->dirmode= mode; 00763 return(1); 00764 } 00765 00766 00767 int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o, 00768 mode_t *mode) 00769 { 00770 *mode= o->dirmode; 00771 return(1); 00772 } 00773 00774 00775 int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o, 00776 char *input_charset) 00777 { 00778 o->input_charset= input_charset; 00779 return(1); 00780 } 00781 00782 00783 int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o, 00784 char **input_charset) 00785 { 00786 *input_charset= o->input_charset; 00787 return(1); 00788 } 00789 00790 00791 int isoburn_ropt_set_auto_incharset(struct isoburn_read_opts *o, int mode) 00792 { 00793 o->auto_input_charset= mode & 1; 00794 return(1); 00795 } 00796 00797 00798 int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode) 00799 { 00800 *mode= o->auto_input_charset; 00801 return(1); 00802 } 00803 00804 00805 int isoburn_ropt_get_size_what(struct isoburn_read_opts *o, 00806 uint32_t *size, int *has_what) 00807 { 00808 *size= o->size; 00809 *has_what= (!!o->hasRR) | ((!!o->hasJoliet)<<1) | 00810 ((!!o->hasIso1999)<<2) | ((!!o->hasElTorito)<<3); 00811 return(1); 00812 } 00813 00814 00815 /* ----------------------------------------------------------------------- */ 00816 /* 00817 Options for image generation by libisofs and image transport to libburn. 00818 */ 00819 /* ----------------------------------------------------------------------- */ 00820 00821 00822 int isoburn_igopt_new(struct isoburn_imgen_opts **new_o, int flag) 00823 { 00824 struct isoburn_imgen_opts *o; 00825 00826 o= (*new_o)= calloc(1, sizeof(struct isoburn_imgen_opts)); 00827 if(o==NULL) { 00828 isoburn_msgs_submit(NULL, 0x00060000, 00829 "Cannot allocate memory for image generation options", 00830 0, "FATAL", 0); 00831 return(-1); 00832 } 00833 o->level= 2; 00834 o->rockridge= 1; 00835 o->joliet= 0; 00836 o->iso1999= 0; 00837 o->hardlinks= 0; 00838 o->aaip = 0; 00839 o->omit_version_numbers= 0; 00840 o->allow_deep_paths= 1; 00841 o->allow_longer_paths= 0; 00842 o->max_37_char_filenames= 0; 00843 o->no_force_dots= 0; 00844 o->allow_lowercase= 0; 00845 o->allow_full_ascii= 0; 00846 o->joliet_longer_paths= 0; 00847 o->always_gmt= 0; 00848 o->rrip_version_1_10= 0; 00849 o->dir_rec_mtime= 0; 00850 o->aaip_susp_1_10= 0; 00851 o->sort_files= 0; 00852 o->replace_dir_mode= 0; 00853 o->replace_file_mode= 0; 00854 o->replace_uid= 0; 00855 o->replace_gid= 0; 00856 o->dir_mode= 0555; 00857 o->file_mode= 0444; 00858 o->uid= 0; 00859 o->gid= 0; 00860 o->output_charset= NULL; 00861 o->fifo_size= 4*1024*1024; 00862 o->effective_lba= -1; 00863 o->data_start_lba= -1; 00864 o->system_area_data= NULL; 00865 o->system_area_options= 0; 00866 o->vol_creation_time= 0; 00867 o->vol_modification_time= 0; 00868 o->vol_expiration_time= 0; 00869 o->vol_effective_time= 0; 00870 return(1); 00871 } 00872 00873 00874 int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag) 00875 { 00876 if(*o==NULL) 00877 return(0); 00878 free(*o); 00879 *o= NULL; 00880 return(1); 00881 } 00882 00883 00884 int isoburn_igopt_set_level(struct isoburn_imgen_opts *o, int level) 00885 { 00886 o->level= level; 00887 return(1); 00888 } 00889 00890 00891 int isoburn_igopt_get_level(struct isoburn_imgen_opts *o, int *level) 00892 { 00893 *level= o->level; 00894 return(1); 00895 } 00896 00897 00898 int isoburn_igopt_set_extensions(struct isoburn_imgen_opts *o, int ext) 00899 { 00900 o->rockridge= !!(ext&1); 00901 o->joliet= !!(ext&2); 00902 o->iso1999= !!(ext&4); 00903 o->hardlinks= !!(ext & 8); 00904 o->aaip= !!(ext & 32); 00905 o->session_md5= !!(ext & 64); 00906 o->file_md5= (ext & (128 | 256)) >> 7; 00907 return(1); 00908 } 00909 00910 00911 int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext) 00912 { 00913 *ext= (!!o->rockridge) | ((!!o->joliet)<<1) | ((!!o->iso1999)<<2) | 00914 ((!!o->hardlinks) << 3) | ((!!o->aaip) << 5) | 00915 ((!!o->session_md5) << 6) | ((o->file_md5 & 3) << 7); 00916 return(1); 00917 } 00918 00919 00920 int isoburn_igopt_set_relaxed(struct isoburn_imgen_opts *o, int relax) 00921 { 00922 o->omit_version_numbers= (!!(relax&1)) | 00923 (2 * !!(relax & isoburn_igopt_only_iso_versions)); 00924 o->allow_deep_paths= !!(relax&2); 00925 o->allow_longer_paths= !!(relax&4); 00926 o->max_37_char_filenames= !!(relax&8); 00927 o->no_force_dots= (!!(relax&16)) | 00928 (2 * !!(relax & isoburn_igopt_no_j_force_dots)); 00929 o->allow_lowercase= !!(relax&32); 00930 o->allow_full_ascii= !!(relax&64); 00931 o->joliet_longer_paths= !!(relax&128); 00932 o->always_gmt= !!(relax & isoburn_igopt_always_gmt); 00933 o->rrip_version_1_10= !!(relax & isoburn_igopt_rrip_version_1_10); 00934 o->dir_rec_mtime= !!(relax & isoburn_igopt_dir_rec_mtime); 00935 o->aaip_susp_1_10= !!(relax & isoburn_igopt_aaip_susp_1_10); 00936 return(1); 00937 } 00938 00939 00940 int isoburn_igopt_get_relaxed(struct isoburn_imgen_opts *o, int *relax) 00941 { 00942 *relax= (!!o->omit_version_numbers) | ((!!o->allow_deep_paths)<<1) | 00943 ((!!o->allow_longer_paths)<<2) | ((!!o->max_37_char_filenames)<<3) | 00944 ((!!o->no_force_dots)<<4) | ((!!o->allow_lowercase)<<5) | 00945 ((!!o->allow_full_ascii)<<6) | ((!!o->joliet_longer_paths)<<7) | 00946 ((!!o->always_gmt)<<8) | ((!!o->rrip_version_1_10)<<9) | 00947 ((!!o->dir_rec_mtime)<<10) | ((!!o->aaip_susp_1_10)<<11); 00948 return(1); 00949 } 00950 00951 00952 int isoburn_igopt_set_sort_files(struct isoburn_imgen_opts *o, int value) 00953 { 00954 o->sort_files= !!(value&1); 00955 return(1); 00956 } 00957 00958 00959 int isoburn_igopt_get_sort_files(struct isoburn_imgen_opts *o, int *value) 00960 { 00961 *value= !!o->sort_files; 00962 return(1); 00963 } 00964 00965 00966 int isoburn_igopt_set_over_mode(struct isoburn_imgen_opts *o, 00967 int replace_dir_mode, int replace_file_mode, 00968 mode_t dir_mode, mode_t file_mode) 00969 { 00970 o->replace_dir_mode= replace_dir_mode%3; 00971 o->replace_file_mode= replace_file_mode%3; 00972 o->dir_mode= dir_mode; 00973 o->file_mode= file_mode; 00974 return(1); 00975 } 00976 00977 00978 int isoburn_igopt_get_over_mode(struct isoburn_imgen_opts *o, 00979 int *replace_dir_mode, int *replace_file_mode, 00980 mode_t *dir_mode, mode_t *file_mode) 00981 { 00982 *replace_dir_mode= o->replace_dir_mode%3; 00983 *replace_file_mode= o->replace_file_mode%3; 00984 *dir_mode= o->dir_mode; 00985 *file_mode= o->file_mode; 00986 return(1); 00987 } 00988 00989 00990 int isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts *o, 00991 int replace_uid, int replace_gid, 00992 uid_t uid, gid_t gid) 00993 { 00994 o->replace_uid= replace_uid%3; 00995 o->replace_gid= replace_gid%3; 00996 o->uid= uid; 00997 o->gid= gid; 00998 return(1); 00999 } 01000 01001 int isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts *o, 01002 int *replace_uid, int *replace_gid, 01003 uid_t *uid, gid_t *gid) 01004 { 01005 *replace_uid= o->replace_uid%3; 01006 *replace_gid= o->replace_gid%3; 01007 *uid= o->uid; 01008 *gid= o->gid; 01009 return(1); 01010 } 01011 01012 01013 int isoburn_igopt_set_out_charset(struct isoburn_imgen_opts *o, 01014 char *output_charset) 01015 { 01016 o->output_charset= output_charset; 01017 return(1); 01018 } 01019 01020 01021 int isoburn_igopt_get_out_charset(struct isoburn_imgen_opts *o, 01022 char **output_charset) 01023 { 01024 *output_charset= o->output_charset; 01025 return(1); 01026 } 01027 01028 01029 int isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts *o, int fifo_size) 01030 { 01031 o->fifo_size= fifo_size; 01032 return(1); 01033 } 01034 01035 01036 int isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts *o, int *fifo_size) 01037 { 01038 *fifo_size= o->fifo_size; 01039 return(1); 01040 } 01041 01042 01043 int isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts *o, int *lba) 01044 { 01045 *lba= o->effective_lba; 01046 return(1); 01047 } 01048 01049 01050 int isoburn_igopt_get_data_start(struct isoburn_imgen_opts *o, int *lba) 01051 { 01052 *lba= o->data_start_lba; 01053 return(1); 01054 } 01055 01056 01057 int isoburn_igopt_set_scdbackup_tag(struct isoburn_imgen_opts *o, char *name, 01058 char *timestamp, char *tag_written) 01059 { 01060 strncpy(o->scdbackup_tag_name, name, 80); 01061 o->scdbackup_tag_name[80]= 0; 01062 strncpy(o->scdbackup_tag_time, timestamp, 18); 01063 o->scdbackup_tag_time[18]= 0; 01064 o->scdbackup_tag_written = tag_written; 01065 if(tag_written != NULL) 01066 tag_written[0]= 0; 01067 return(1); 01068 } 01069 01070 01071 int isoburn_igopt_get_scdbackup_tag(struct isoburn_imgen_opts *o, 01072 char name[81], char timestamp[19], 01073 char **tag_written) 01074 { 01075 strncpy(name, o->scdbackup_tag_name, 80); 01076 name[80]= 0; 01077 strncpy(timestamp, o->scdbackup_tag_time, 18); 01078 timestamp[18]= 0; 01079 *tag_written= o->scdbackup_tag_written; 01080 return(1); 01081 } 01082 01083 01084 int isoburn_igopt_set_system_area(struct isoburn_imgen_opts *opts, 01085 char data[32768], int options) 01086 { 01087 if (data == NULL) { /* Disable */ 01088 if (opts->system_area_data != NULL) 01089 free(opts->system_area_data); 01090 opts->system_area_data = NULL; 01091 } else { 01092 if (opts->system_area_data == NULL) { 01093 opts->system_area_data = calloc(32768, 1); 01094 if (opts->system_area_data == NULL) 01095 return(-1); 01096 } 01097 memcpy(opts->system_area_data, data, 32768); 01098 } 01099 opts->system_area_options = options & 3; 01100 return(1); 01101 } 01102 01103 01104 int isoburn_igopt_get_system_area(struct isoburn_imgen_opts *opts, 01105 char data[32768], int *options) 01106 { 01107 *options= opts->system_area_options; 01108 if(opts->system_area_data == NULL) 01109 return(0); 01110 memcpy(data, opts->system_area_data, 32768); 01111 return(1); 01112 } 01113 01114 01115 int isoburn_igopt_set_pvd_times(struct isoburn_imgen_opts *opts, 01116 time_t vol_creation_time, time_t vol_modification_time, 01117 time_t vol_expiration_time, time_t vol_effective_time, 01118 char *vol_uuid) 01119 { 01120 opts->vol_creation_time = vol_creation_time; 01121 opts->vol_modification_time = vol_modification_time; 01122 opts->vol_expiration_time = vol_expiration_time; 01123 opts->vol_effective_time = vol_effective_time; 01124 strncpy(opts->vol_uuid, vol_uuid, 16); 01125 opts->vol_uuid[16] = 0; 01126 return(1); 01127 } 01128 01129 01130 int isoburn_igopt_get_pvd_times(struct isoburn_imgen_opts *opts, 01131 time_t *vol_creation_time, time_t *vol_modification_time, 01132 time_t *vol_expiration_time, time_t *vol_effective_time, 01133 char vol_uuid[17]) 01134 { 01135 *vol_creation_time = opts->vol_creation_time; 01136 *vol_modification_time = opts->vol_modification_time; 01137 *vol_expiration_time = opts->vol_expiration_time; 01138 *vol_effective_time = opts->vol_effective_time; 01139 strcpy(vol_uuid, opts->vol_uuid); 01140 return(1); 01141 } 01142 01143
1.7.3