1/* See LICENSE file for copyright and license details. */
2
3
4#include <sys/ioctl.h>
5#include <sys/stat.h>
6#include <sys/types.h>
7
8#include <fcntl.h>
9#include <stdio.h>
10#include <unistd.h>
11
12#include "util.h"
13
14enum {
15 OPEN_TRAY = 0x5309,
16 CLOSE_TRAY = 0x5319,
17};
18
19static int tflag = 0;
20static int ret = 0;
21
22static void
23eject(const char *devname)
24{
25 int fd, out;
26
27 if ((fd = open(devname, O_RDONLY | O_NONBLOCK)) < 0) {
28 weprintf("open %s:", devname);
29 ret = 1;
30 } else if (tflag && ioctl(fd, CLOSE_TRAY, &out) < 0) {
31 weprintf("ioctl %s:", devname);
32 ret = 1;
33 } else if (!tflag && ioctl(fd, OPEN_TRAY, &out) < 0) {
34 weprintf("ioctl %s:", devname);
35 ret = 1;
36 }
37
38 if (fd >= 0 && close(fd) < 0) {
39 weprintf("close %s:", devname);
40 ret = 1;
41 }
42}
43
44
45static void
46usage(void)
47{
48 eprintf("usage: %s [-t] [device ...]\n", argv0);
49}
50
51// ?man eject: eject removable media
52// ?man arguments: device ...
53// ?man eject optical discs or other removable storage media
54int
55main(int argc, char *argv[])
56{
57 ARGBEGIN {
58 // ?man -t: sort or specify timestamp
59 case 't':
60 tflag = 1;
61 break;
62 default:
63 usage();
64 } ARGEND;
65
66 if (!argc) {
67 eject("/dev/sr0");
68 } else {
69 for (; *argv; argc--, argv++)
70 eject(*argv);
71 }
72
73 return ret;
74}