--- eject.c.orig Tue Jan 4 15:42:12 2000 +++ eject.c Sun Feb 1 17:59:10 2004 @@ -43,8 +43,8 @@ extern int optind; void usage(void); -int check_device(char *, char *); -int unmount_fs(char *, char *); +int check_device(char *, char **); +int unmount_fs(char *, char **); int eject(char *, char *); char *program = "eject"; @@ -52,6 +52,7 @@ int fflag; /* force unmount filesystem */ int nflag; /* not execute operation */ int vflag; /* verbose operation */ +int tflag; /* tray close */ /* * simple eject program @@ -65,14 +66,14 @@ { int ch; int sts; - char device[256], name[256]; - char err[256]; + char *device, *name; + char *err; char *defdev; - fflag = nflag = vflag = 0; + fflag = nflag = vflag = tflag = 0; defdev = getenv("EJECT"); - while ((ch = getopt(argc, argv, "fnv?")) != EOF) { + while ((ch = getopt(argc, argv, "fnvt?")) != EOF) { switch (ch) { case 'f' : fflag = 1; @@ -83,6 +84,9 @@ case 'v' : vflag = 1; break; + case 't' : + tflag = 1; + break; case '?' : default : usage(); @@ -95,18 +99,51 @@ if (argc == 0) { usage(); } - strcpy(name, *argv); + name = strdup(*argv); } else { - strcpy(name, defdev); + name = strdup(defdev); } - sts = check_device(name, device); + sts = check_device(name, &device); if (sts < 0) { perror(program); exit(1); + } else { + int c; + char *dev_bak = malloc(MAXPATHLEN); + free(name); + if ((c = readlink(device, dev_bak, MAXPATHLEN))>0) { + dev_bak[c] = '\0'; + name = dev_bak; + } else { + free(dev_bak); + name = device; + } + if (strncmp(device, "/dev/", 5) != 0) + { + int mnts; + struct statfs *mntbuf; + mnts = getmntinfo(&mntbuf, MNT_NOWAIT); + if (mnts == 0) { + perror(program); + exit(1); + } + for (ch = 0; ch < mnts; ch++) { + if (strcmp(mntbuf[ch].f_mntonname, name) == 0) { + device = strdup(mntbuf[ch].f_mntfromname); + name = strdup(mntbuf[ch].f_mntfromname); + break; + } + } + if (strncmp(device, "/dev/", 5) != 0) + { + perror(program); + exit(1); + } + } } - sts = unmount_fs(name, err); + sts = unmount_fs(name, &err); if (sts < 0) { perror(err); exit(1); @@ -128,16 +165,26 @@ int check_device(name, device) char *name; - char *device; + char **device; { - int sts; + int sts = 0, i; struct stat sb; - sprintf(device, "/dev/r%sc", name); - if (vflag || nflag) { - printf("%s: using device %s\n", program, device); + const char* dev_list[] = { "/dev/%sc", "/dev/%s", "%s" }; + for (i = 0; i < 3; i++) { + if ((sts = asprintf(device, dev_list[i], name)) == -1) + return sts; + if (vflag || nflag) { + printf("%s: trying device %s\n", program, *device); + } + sts = stat(*device, &sb); + if (sts) { /* stat failed, try next */ + free(*device); + continue; + } else { + break; + } } - sts = stat(device, &sb); return sts; } @@ -155,7 +202,7 @@ int unmount_fs(name, err) char *name; - char *err; + char **err; { int mnts; struct statfs *mntbuf; @@ -173,7 +220,7 @@ /* get proper mount information into the list */ len = strlen(name); for (n = 0; n < mnts; n++) { - p = rindex(mntbuf[n].f_mntfromname, '/'); + p = mntbuf[n].f_mntfromname - 1; if (p == NULL) { continue; } @@ -221,7 +268,7 @@ sts = 0; } if (sts < 0 && fflag == 0) { - sprintf(err, "%s: %s", program, mp->mntonname); + asprintf(err, "%s: %s", program, mp->mntonname); return sts; } nextp = mp->next; @@ -255,14 +302,26 @@ } if (!nflag) { if (vflag) { - printf("%s: ejecting media from %s\n", program, name); + if (tflag) { + printf("%s: tray close on %s\n", program, name); + } else { + printf("%s: ejecting media from %s\n", program, name); + } } sts = ioctl(fd, CDIOCALLOW); if (sts >= 0) { - sts = ioctl(fd, CDIOCEJECT); + if (tflag) { + sts = ioctl(fd, CDIOCCLOSE); + } else { + sts = ioctl(fd, CDIOCEJECT); + } } } else { - printf("%s: ejecting media from %s\n", program, name); + if (tflag) { + printf("%s: tray close on %s\n", program, name); + } else { + printf("%s: ejecting media from %s\n", program, name); + } sts = 0; } close(fd); @@ -277,6 +336,6 @@ void usage(void) { - fprintf(stderr, "usage: %s [-fnv] device\n", program); + fprintf(stderr, "usage: %s [-fnvt] device\n", program); exit(1); }