00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <unistd.h>
00013 #include <getopt.h>
00014 #include <err.h>
00015 #include <string.h>
00016 #include <errno.h>
00017 #include <sys/stat.h>
00018
00019
00020 #include <libisofs/libisofs.h>
00021 #include <libburn/libburn.h>
00022 #include "../src/libisoburn.h"
00023
00024 const char * const optstring = "JRh";
00025 extern char *optarg;
00026 extern int optind;
00027
00028
00029
00030
00031
00032 #define With_graft_poinT 1
00033
00034
00035 static int graft_point(struct iso_volume *volume, const char *disk_path,
00036 const char *img_path, struct iso_tree_radd_dir_behavior *behav)
00037 {
00038 char path[4096], *apt, *npt;
00039 struct iso_tree_node_dir *dir;
00040 struct iso_tree_node *node;
00041 int done= 0, is_dir= 0;
00042 struct stat stbuf;
00043
00044 strncpy(path, img_path, sizeof(path)-1);
00045 path[sizeof(path)-1]= 0;
00046 apt= npt= path;
00047
00048 if(lstat(disk_path, &stbuf) == -1) {
00049 fprintf(stderr, "Cannot determine attributes of '%s' : %s (%d)\n",
00050 disk_path, (errno > 0 ? strerror(errno) : "unknown error"), errno);
00051 return(0);
00052 }
00053 if(S_ISDIR(stbuf.st_mode))
00054 is_dir= 1;
00055 else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) {
00056 fprintf(stderr, "File object '%s' is of non-supported file type\n",
00057 disk_path);
00058 return(0);
00059 }
00060
00061 dir= iso_volume_get_root(volume);
00062 if(dir==NULL) {
00063 fprintf(stderr, "While grafting '%s' : no root node available\n", img_path);
00064 return(0);
00065 }
00066 for(npt= apt; !done; apt= npt+1) {
00067 npt= strchr(apt, '/');
00068 if(npt==NULL) {
00069 npt= apt+strlen(apt);
00070 done= 1;
00071 } else
00072 *npt= 0;
00073 if(*apt==0) {
00074 *apt= '/';
00075 apt++;
00076 continue;
00077 }
00078 node= iso_tree_volume_path_to_node(volume,path);
00079 if(node!=NULL) {
00080 if(iso_tree_node_get_type(node)!=LIBISO_NODE_DIR) {
00081 fprintf(stderr, "While grafting '%s' : '%s' is not a directory\n",
00082 img_path, path);
00083 return(0);
00084 }
00085 dir= (struct iso_tree_node_dir *) node;
00086 } else {
00087 dir= iso_tree_add_dir(dir, apt);
00088 if(dir==NULL) {
00089 fprintf(stderr, "While grafting '%s' : could not insert '%s'\n",
00090 img_path, path);
00091 return(0);
00092 }
00093 }
00094 if(done) {
00095 if(is_dir) {
00096 iso_tree_radd_dir(dir, disk_path, behav);
00097 } else {
00098 node= iso_tree_add_node(dir, disk_path);
00099 if(node == NULL) {
00100 fprintf(stderr, "While grafting '%s'='%s' : libisofs_errno = %d\n",
00101 img_path, disk_path, libisofs_errno);
00102 }
00103 }
00104 } else
00105 *npt= '/';
00106 }
00107 fprintf(stderr, "NOTE: added %s '%s'='%s'\n", (is_dir ? "directory" : "node"),
00108 img_path, disk_path);
00109 return(1);
00110 }
00111
00112
00113 static
00114 void usage()
00115 {
00116 printf("test [OPTIONS] DRIVE DIRECTORY\n");
00117 }
00118
00119 static
00120 void help()
00121 {
00122 printf(
00123 "Options:\n"
00124 " -J Add Joliet support\n"
00125 " -R Add Rock Ridge support\n"
00126 " -h Print this message\n"
00127 );
00128 }
00129
00130 int main(int argc, char **argv)
00131 {
00132 struct burn_drive_info *drives;
00133 struct iso_volset *volset;
00134 struct burn_drive *drive;
00135 struct burn_disc *disc;
00136 enum burn_disc_status state;
00137 struct isoburn_read_opts ropts;
00138 struct isoburn_source_opts sopts;
00139 int c;
00140 struct iso_tree_radd_dir_behavior behav = {0,0,0};
00141 int flags=0;
00142 int ret=0, i;
00143 int size, free_bytes;
00144 char *status_text;
00145
00146 while ((c = getopt(argc, argv, optstring)) != -1) {
00147 switch(c) {
00148 case 'h':
00149 usage();
00150 help();
00151 exit(0);
00152 break;
00153 case 'J':
00154 flags |= ECMA119_JOLIET;
00155 break;
00156 case 'R':
00157 flags |= ECMA119_ROCKRIDGE;
00158 break;
00159 case '?':
00160 usage();
00161 exit(1);
00162 break;
00163 }
00164 }
00165
00166 if (argc < optind + 1) {
00167 fprintf(stderr, "Please supply device name\n");
00168 usage();
00169 exit(1);
00170 }
00171 if (argc < optind + 2) {
00172 fprintf(stderr, "Please supply directory to add to disc\n");
00173 usage();
00174 exit(1);
00175 }
00176
00177
00178 if (!isoburn_initialize()) {
00179 fprintf(stderr, "Can't init libisoburn\n");
00180 exit(1);
00181 }
00182
00183
00184 iso_msgs_set_severities("NEVER", "DEBUG", "libisofs : ");
00185 burn_msgs_set_severities("NEVER", "DEBUG", "libburn : ");
00186 burn_set_signal_handling("libisoburn/test/test : ", NULL, 0);
00187
00188 printf("Growing drive %s\n", argv[optind]);
00189
00190 if (isoburn_drive_scan_and_grab(&drives, argv[optind], 1) <= 0) {
00191 fprintf(stderr,
00192 "Can't open device. Are you sure it is a valid drive?\n");
00193 exit(1);
00194 }
00195 drive = drives[0].drive;
00196
00197
00198 state = isoburn_disc_get_status(drive);
00199 if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) {
00200 fprintf(stderr, "Unsuitable disc status\n");
00201 goto exit_cleanup;
00202 }
00203
00204
00205 memset(&ropts, sizeof(ropts), 0);
00206 ropts.norock = 0;
00207 ropts.nojoliet = 0;
00208 ropts.preferjoliet = 0;
00209 ropts.uid = 0;
00210 ropts.gid = 0;
00211 ropts.mode = 0555;
00212 ropts.pretend_blank= 0;
00213
00214 if (isoburn_read_volset(drive, &ropts, &volset) <= 0) {
00215 fprintf(stderr, "Can't read volset\n");
00216 goto exit_cleanup;
00217 }
00218
00219
00220 #ifdef With_graft_poinT
00221 for (i = optind + 1; i < argc; i++) {
00222 if (graft_point(iso_volset_get_volume(volset, 0),
00223 argv[i], argv[i], &behav) <= 0) {
00224 fprintf(stderr, "Canot graft '%s'\n", argv[optind+1]);
00225 goto exit_cleanup;
00226 }
00227 }
00228
00229 #else
00230 struct iso_tree_node_dir *root;
00231 root = iso_volume_get_root(iso_volset_get_volume(volset, 0));
00232
00233 iso_tree_radd_dir(root, argv[optind+1], &behav);
00234 #endif
00235
00236
00237 sopts.level = 2;
00238 sopts.flags = flags;
00239 sopts.relaxed_constraints = 0;
00240 sopts.copy_eltorito = 1;
00241 sopts.no_cache_inodes = 0;
00242 sopts.sort_files = 1;
00243 sopts.default_mode = 0;
00244 sopts.replace_dir_mode = 0;
00245 sopts.replace_file_mode = 0;
00246 sopts.replace_uid = 0;
00247 sopts.replace_gid = 0;
00248 sopts.dir_mode = 0555;
00249 sopts.file_mode = 0444;
00250 sopts.gid = 0;
00251 sopts.uid = 0;
00252 sopts.input_charset = NULL;
00253 sopts.ouput_charset = NULL;
00254
00255 if (isoburn_prepare_disc(drive, &disc, &sopts) <= 0) {
00256 fprintf(stderr, "Can't prepare disc\n");
00257 goto volset_cleanup;
00258 }
00259
00260
00261 printf("Adding new data...\n");
00262 {
00263 struct burn_write_opts *burn_options;
00264 struct burn_progress progress;
00265
00266 burn_options = burn_write_opts_new(drive);
00267 burn_drive_set_speed(drive, 0, 0);
00268 burn_write_opts_set_underrun_proof(burn_options, 1);
00269
00270
00271 isoburn_disc_write(burn_options, disc);
00272 burn_write_opts_free(burn_options);
00273
00274 while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
00275 usleep(100002);
00276
00277 while (burn_drive_get_status(drive, &progress)
00278 != BURN_DRIVE_IDLE) {
00279
00280 printf("Writing: sector %d of %d",
00281 progress.sector, progress.sectors);
00282 ret = isoburn_get_fifo_status(drive, &size,
00283 &free_bytes, &status_text);
00284 if (ret > 0 )
00285 printf(" [fifo %s, %2d%% fill]", status_text,
00286 (int) (100.0 - 100.0 *
00287 ((double) free_bytes) /
00288 (double) size));
00289 printf("\n");
00290 sleep(1);
00291 }
00292 }
00293
00294
00295 printf("Writing the new vol desc...\n");
00296 if (isoburn_activate_session(drive) <= 0) {
00297 fprintf(stderr, "Ups, new vol desc write failed\n");
00298 }
00299
00300 ret= 0;
00301 volset_cleanup:;
00302
00303
00304
00305
00306 exit_cleanup:;
00307 isoburn_drive_release(drive, 0);
00308 isoburn_finish();
00309
00310 exit(ret);
00311 }
00312