1/* See LICENSE file for copyright and license details. */
2
3#include <sys/ioctl.h>
4#include <sys/stat.h>
5#include <sys/types.h>
6
7#include <fcntl.h>
8#include <stdio.h>
9#include <unistd.h>
10
11#include "paths.h"
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
44static void
45usage(void)
46{
47 eprintf("usage: %s [-t] [device ...]\n", argv0);
48}
49
50// ?man eject: eject removable media
51// ?man arguments: device ...
52// ?man eject optical discs or other removable storage media
53int
54main(int argc, char *argv[])
55{
56 ARGBEGIN
57 {
58 // ?man -t: sort or specify timestamp
59 case 't':
60 tflag = 1;
61 break;
62 default:
63 usage();
64 }
65 ARGEND;
66
67 if (!argc) {
68 eject(ARUU_PATH_DEV "/sr0");
69 } else {
70 for (; *argv; argc--, argv++)
71 eject(*argv);
72 }
73
74 return ret;
75}