1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <sys/types.h> 32 #include <limits.h> 33 #include <unistd.h> 34 #include <libintl.h> 35 #include <locale.h> 36 #include <volmgt.h> 37 38 #include "msgs.h" 39 #include "device.h" 40 #include "util.h" 41 #include "main.h" 42 #include "options.h" 43 #include "mmc.h" 44 #include "misc_scsi.h" 45 46 /* 47 * global flags 48 */ 49 int debug = 0; 50 int use_media_stated_capacity = 0; 51 int keep_disc_open = 0; 52 int requested_speed = 0; 53 int simulation = 0; 54 int verbose = 0; 55 char *image_file = NULL; 56 char *blanking_type = NULL; 57 int audio_type = AUDIO_TYPE_NONE; 58 int extract_track_no = 0; 59 char *extract_file = NULL; 60 char *alt_tmp_dir = NULL; 61 char *copy_src = NULL; 62 int vol_running = 0; 63 int cflag = 0; 64 int tflag = 0; 65 uid_t ruid, cur_uid; 66 67 /* 68 * global variables 69 */ 70 cd_device *target = NULL; /* Default target device */ 71 static char *tgtdev = NULL; 72 int device_type = CD_RW; /* Default to CD/RW */ 73 int write_mode = TAO_MODE; /* Default to track at once */ 74 75 static void 76 print_usage(void) 77 { 78 err_msg(gettext("USAGE:\n")); 79 err_msg(gettext("\tcdrw -i [ -vSCO ] [ -d device ] [ -p speed ]")); 80 err_msg(gettext(" [ image-file ]\n")); 81 err_msg(gettext("\tcdrw -a [ -vSCO ] [ -d device ] [ -p speed ]")); 82 err_msg(gettext(" [ -T audio-type ] audio-file1 audio-file2 ...\n")); 83 err_msg(gettext("\tcdrw -x [ -v ] [ -d device ] [ -T audio-type ]")); 84 err_msg(gettext(" track-number audio-file\n")); 85 err_msg(gettext("\tcdrw -c [ -cSC ] [ -d device ] [ -p speed ]")); 86 err_msg(gettext(" [ -m tmp-dir ] [ -s src-device ]\n")); 87 err_msg( 88 gettext("\tcdrw -b [ -v ] [ -d device ] all | session | fast\n")); 89 err_msg(gettext("\tcdrw -M [ -v ] [ -d device ]\n")); 90 err_msg(gettext("\tcdrw -L [v] [ -d device ]\n")); 91 err_msg(gettext("\tcdrw -l [ -v ]\n")); 92 err_msg(gettext("\tcdrw -h\n")); 93 94 exit(2); 95 } 96 97 static void 98 check_invalid_option(options *specified, char *opstr) 99 { 100 options c_op; 101 int ret; 102 103 set_options_mask(&c_op, opstr); 104 if ((ret = compare_options_mask(&c_op, specified)) != 0) { 105 err_msg( 106 gettext("Option %c is not defined for this operation.\n"), 107 (char)ret); 108 print_usage(); 109 } 110 } 111 112 int 113 setup_target(int flag) 114 { 115 char *devpath; 116 117 if (tgtdev != NULL) { 118 devpath = (char *)my_zalloc(PATH_MAX); 119 if (lookup_device(tgtdev, devpath)) { 120 target = get_device(tgtdev, devpath); 121 } 122 free(devpath); 123 if (target == NULL) { 124 return (0); 125 } 126 return (1); 127 } 128 return (scan_for_cd_device(flag, &target)); 129 } 130 131 void 132 main(int argc, char **argv) 133 { 134 int c; 135 int operations; 136 options specified_ops; 137 int aflag, iflag, Mflag, Lflag, lflag, bflag, xflag; 138 int ret; 139 140 (void) setlocale(LC_ALL, ""); 141 142 #if !defined(TEXT_DOMAIN) 143 #define TEXT_DOMAIN "SYS_TEST" 144 #endif 145 146 147 (void) textdomain(TEXT_DOMAIN); 148 149 ruid = getuid(); 150 cur_uid = geteuid(); 151 152 if (check_auth(ruid) != 1) { 153 err_msg(gettext( 154 "Authorization failed, Cannot access disks.\n")); 155 exit(1); 156 } 157 158 if ((cur_uid == 0) && (ruid != 0)) { 159 priv_change_needed = 1; 160 lower_priv(); 161 } 162 163 vol_running = volmgt_running(); 164 165 tgtdev = NULL; 166 operations = 0; 167 set_options_mask(&specified_ops, ""); 168 iflag = Mflag = Lflag = lflag = bflag = aflag = xflag = cflag = 0; 169 170 while ((c = getopt(argc, argv, "abcCd:hiLlm:MOp:s:ST:vVx")) != EOF) { 171 add_option(&specified_ops, c); 172 switch (c) { 173 case 'a': 174 aflag = 1; 175 operations++; 176 break; 177 case 'b': 178 bflag = 1; 179 operations++; 180 break; 181 case 'c': 182 cflag = 1; 183 operations++; 184 break; 185 case 'C': 186 use_media_stated_capacity = 1; 187 break; 188 case 'd': 189 tgtdev = optarg; 190 break; 191 case 'h': 192 print_usage(); /* will not return */ 193 break; 194 case 'i': 195 iflag = 1; 196 operations++; 197 break; 198 case 'L': 199 Lflag = 1; 200 operations++; 201 break; 202 case 'l': 203 lflag = 1; 204 operations++; 205 break; 206 case 'm': 207 alt_tmp_dir = optarg; 208 break; 209 case 'M': 210 Mflag = 1; 211 operations++; 212 break; 213 case 'O': 214 keep_disc_open = 1; 215 break; 216 case 'p': 217 requested_speed = atoi(optarg); 218 break; 219 case 's': 220 copy_src = optarg; 221 break; 222 case 'S': 223 simulation++; 224 break; 225 case 'T': 226 audio_type = get_audio_type(optarg); 227 if (audio_type == -1) { 228 err_msg(gettext("Unknown audio type %s\n"), 229 optarg); 230 exit(1); 231 } 232 break; 233 case 'v': 234 verbose++; 235 break; 236 case 'V': 237 /* 238 * more verbose. this will print out debug comments 239 */ 240 241 debug++; 242 break; 243 case 'x': 244 xflag++; 245 operations++; 246 break; 247 default: 248 print_usage(); 249 } 250 } 251 if (operations == 0) { 252 err_msg(gettext("No operation specified.\n")); 253 exit(1); 254 } 255 if (operations != 1) { 256 err_msg(gettext("More than one operation specified.\n")); 257 exit(1); 258 } 259 260 if (lflag) { 261 check_invalid_option(&specified_ops, "lhvV"); 262 list(); 263 } 264 265 /* 266 * we'll allow the user to specify the source device (-s) when 267 * extracting audio. 268 */ 269 270 if (xflag && copy_src) 271 tgtdev = copy_src; 272 273 /* 274 * This will scan for all CD devices when xflag or Mflag 275 * (extract audio, list toc) commands are used, providing 276 * no CD-RW devices are found. Since these commands can 277 * be used without a CD writer. 278 */ 279 280 if (xflag || Mflag) { 281 ret = setup_target(SCAN_ALL_CDS); 282 } else { 283 ret = setup_target(SCAN_WRITERS); 284 } 285 286 if (ret == 0) { 287 288 if (tgtdev != NULL) { 289 err_msg(gettext( 290 "Cannot find device %s.\n"), tgtdev); 291 292 } 293 294 if (vol_running) { 295 err_msg(gettext( 296 "No CD writers found or no media in the drive.\n")); 297 } else { 298 if (cur_uid != 0) { 299 err_msg(gettext( 300 "Volume manager is not running.\n")); 301 err_msg(gettext( 302 "Please start volume manager or run cdrw as root to access all devices.\n")); 303 } else { 304 err_msg(gettext( 305 "No CD writers found.\n")); 306 } 307 } 308 exit(1); 309 310 } else if (ret != 1) { 311 err_msg(gettext("More than one CD device found.\n")); 312 err_msg(gettext("Specify one using -d option.\n")); 313 err_msg(gettext( 314 "Or use -l option to list all the CD devices found\n")); 315 exit(1); 316 } 317 (void) check_device(target, CHECK_TYPE_NOT_CDROM|EXIT_IF_CHECK_FAILED); 318 319 if (check_device(target, CHECK_NO_MEDIA) == 0) { 320 int retry; 321 for (retry = 0; retry < 5; retry++) { 322 if (check_device(target, CHECK_DEVICE_NOT_READY) == 0) 323 break; 324 (void) sleep(3); 325 } 326 } 327 328 if (aflag) { 329 check_invalid_option(&specified_ops, "ahvSCOdpTV"); 330 if (optind == argc) { 331 err_msg(gettext("No audio files specified.\n")); 332 exit(1); 333 } 334 write_audio(argv, optind, argc); 335 } 336 if (Mflag) { 337 check_invalid_option(&specified_ops, "MhvdV"); 338 info(); 339 } 340 if (iflag) { 341 check_invalid_option(&specified_ops, "ihvSCOdpV"); 342 if (optind == (argc - 1)) { 343 image_file = argv[optind]; 344 write_image(); 345 } 346 if (optind == argc) 347 write_image(); 348 err_msg(gettext("Command line parsing error.\n")); 349 err_msg(gettext("Only one image-file can be specified.\n")); 350 exit(1); 351 } 352 if (bflag) { 353 check_invalid_option(&specified_ops, "bhvdV"); 354 if (optind != (argc - 1)) { 355 err_msg(gettext("Command line parsing error.\n")); 356 print_usage(); 357 } 358 blanking_type = argv[argc - 1]; 359 blank(); 360 } 361 if (xflag) { 362 check_invalid_option(&specified_ops, "xhpvdsTV"); 363 if (optind != (argc - 2)) { 364 err_msg(gettext("Command line parsing error.\n")); 365 print_usage(); 366 } 367 extract_track_no = atoi(argv[argc - 2]); 368 extract_file = argv[argc - 1]; 369 extract_audio(); 370 } 371 if (cflag) { 372 check_invalid_option(&specified_ops, "chvSCdpmsV"); 373 copy_cd(); 374 } 375 376 /* 377 * Open a closed disk, we do this by erasing the track tail 378 * and then re-finalizing with an open leadout. 379 */ 380 if (Lflag) { 381 check_invalid_option(&specified_ops, "LvdV"); 382 (void) check_device(target, CHECK_NO_MEDIA | 383 CHECK_DEVICE_NOT_READY | EXIT_IF_CHECK_FAILED); 384 385 /* no need to erase blank media */ 386 if (!check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) 387 exit(0); 388 389 blanking_type = "leadout"; 390 blank(); 391 392 write_init(TRACK_MODE_DATA); 393 (void) close_track(target->d_fd, 0, 1, 1); 394 (void) finalize(target); 395 (void) printf(gettext("done.\n")); 396 exit(0); 397 } 398 399 } 400