int eject_main(int argc UNUSED_PARAM, char **argv) { unsigned flags; const char *device; opt_complementary = "?1:t--T:T--t"; flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); device = argv[optind] ? argv[optind] : "/dev/cdrom"; /* We used to do "umount <device>" here, but it was buggy if something was mounted OVER cdrom and if cdrom is mounted many times. This works equally well (or better): #!/bin/sh umount /dev/cdrom eject /dev/cdrom */ xmove_fd(xopen_nonblocking(device), dev_fd); if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI)) eject_scsi(device); else eject_cdrom(flags, device); if (ENABLE_FEATURE_CLEAN_UP) close(dev_fd); return EXIT_SUCCESS; }
/* main program */ int main(int argc, char **argv) { char *device = NULL; char *disk = NULL; char *mountpoint = NULL; int worked = 0; /* set to 1 when successfully ejected */ int fd; /* file descriptor for device */ setlocale(LC_ALL,""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); /* parse the command line arguments */ parse_args(argc, argv, &device); /* handle -d option */ if (d_option) { info(_("default device: `%s'"), EJECT_DEFAULT_DEVICE); return EXIT_SUCCESS; } if (!device) { device = mnt_resolve_path(EJECT_DEFAULT_DEVICE, NULL); verbose(_("using default device `%s'"), device); } else { char *p; if (device[strlen(device)-1] == '/') device[strlen(device)-1] = '\0'; /* figure out full device or mount point name */ p = find_device(device); if (p) free(device); else p = device; device = mnt_resolve_spec(p, NULL); free(p); } if (!device) errx(EXIT_FAILURE, _("%s: unable to find device"), device); verbose(_("device name is `%s'"), device); device_get_mountpoint(&device, &mountpoint); if (mountpoint) verbose(_("%s: mounted on %s"), device, mountpoint); else verbose(_("%s: not mounted"), device); disk = get_disk_devname(device); if (disk) { verbose(_("%s: disc device: %s (disk device will be used for eject)"), device, disk); free(device); device = disk; disk = NULL; } else { struct stat st; if (stat(device, &st) != 0 || !S_ISBLK(st.st_mode)) errx(EXIT_FAILURE, _("%s: not found mountpoint or device " "with the given name"), device); verbose(_("%s: is whole-disk device"), device); } if (F_option == 0 && is_hotpluggable(device) == 0) errx(EXIT_FAILURE, _("%s: is not hot-pluggable device"), device); /* handle -n option */ if (n_option) { info(_("device is `%s'"), device); verbose(_("exiting due to -n/--noop option")); return EXIT_SUCCESS; } /* handle -i option */ if (i_option) { fd = open_device(device); manual_eject(fd, i_arg); return EXIT_SUCCESS; } /* handle -a option */ if (a_option) { if (a_arg) verbose(_("%s: enabling auto-eject mode"), device); else verbose(_("%s: disabling auto-eject mode"), device); fd = open_device(device); auto_eject(fd, a_arg); return EXIT_SUCCESS; } /* handle -t option */ if (t_option) { verbose(_("%s: closing tray"), device); fd = open_device(device); close_tray(fd); set_device_speed(device); return EXIT_SUCCESS; } /* handle -T option */ if (T_option) { verbose(_("%s: toggling tray"), device); fd = open_device(device); toggle_tray(fd); set_device_speed(device); return EXIT_SUCCESS; } /* handle -X option */ if (X_option) { verbose(_("%s: listing CD-ROM speed"), device); fd = open_device(device); list_speeds(device, fd); return EXIT_SUCCESS; } /* handle -x option only */ if (!c_option) set_device_speed(device); /* * Unmount all partitions if -m is not specified; or umount given * mountpoint if -M is specified, otherwise print error of another * partition is mounted. */ if (!m_option) { int ct = umount_partitions(device, M_option); if (ct == 0 && mountpoint) umount_one(mountpoint); /* probably whole-device */ if (M_option) { if (ct == 1 && mountpoint) umount_one(mountpoint); else if (ct) errx(EXIT_FAILURE, _("error: %s: device in use"), device); } } /* handle -c option */ if (c_option) { verbose(_("%s: selecting CD-ROM disc #%ld"), device, c_arg); fd = open_device(device); changer_select(fd, c_arg); set_device_speed(device); return EXIT_SUCCESS; } /* if user did not specify type of eject, try all four methods */ if (r_option + s_option + f_option + q_option == 0) r_option = s_option = f_option = q_option = 1; /* open device */ fd = open_device(device); /* try various methods of ejecting until it works */ if (r_option) { verbose(_("%s: trying to eject using CD-ROM eject command"), device); worked = eject_cdrom(fd); verbose(worked ? _("CD-ROM eject command succeeded") : _("CD-ROM eject command failed")); } if (s_option && !worked) { verbose(_("%s: trying to eject using SCSI commands"), device); worked = eject_scsi(fd); verbose(worked ? _("SCSI eject succeeded") : _("SCSI eject failed")); } if (f_option && !worked) { verbose(_("%s: trying to eject using floppy eject command"), device); worked = eject_floppy(fd); verbose(worked ? _("floppy eject command succeeded") : _("floppy eject command failed")); } if (q_option && !worked) { verbose(_("%s: trying to eject using tape offline command"), device); worked = eject_tape(fd); verbose(worked ? _("tape offline command succeeded") : _("tape offline command failed")); } if (!worked) errx(EXIT_FAILURE, _("unable to eject")); /* cleanup */ close(fd); free(device); free(mountpoint); mnt_unref_table(mtab); return EXIT_SUCCESS; }