?? eject.c
字號:
/* * L I N U X E J E C T C O M M A N D * * Copyright (C) 1994-96 Jeff Tranter (Jeff_Tranter@Mitel.COM) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * ******************************************************************** * * See the man page for a description of what this program does and what * the requirements to run it are. * * It was developed using: * - Linux kernel 1.1.72 * - gcc 2.5.8 * - Panasonic CR-562-B CD-ROM drive * * Jeff Tranter (Jeff_Tranter@Mitel.COM) */#include <stdlib.h>#include <sys/types.h>#include <sys/ioctl.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <sys/mount.h>#include <linux/cdrom.h>/* set the default device here */char default_device[255];/* default options */int f_option = 0; /* force eject even if mounted */int d_option = 0; /* display default device */int n_option = 0; /* display nicknames */int a_option = 0; /* auto-eject */int a_arg = 0; /* argument to -a option */int v_option = 0; /* verbose mode */int u_option = 0; /* unmount first */char device[256]; /* device name */typedef struct { char *name; char *device;} nickname_t;/* table of device nicknames */nickname_t nickname[] = { { "cdrom", "/dev/cdrom" }, { "sbpcd" , "/dev/sbpcd" }, { "sbpcd0", "/dev/sbpcd0" }, { "sbpcd1", "/dev/sbpcd1" }, { "sbpcd2", "/dev/sbpcd2" }, { "sbpcd3", "/dev/sbpcd3" }, { "cdu31a", "/dev/cdu31a" }, { "cdu535", "/dev/cdu535" }, { "mcd", "/dev/mcd" }, { "lmscd", "/dev/lmscd" }, { "scd0", "/dev/scd0" }, { "scd1", "/dev/scd1" }, { "cd0", "/dev/cd0" }, { "cd1", "/dev/cd1" }, { "sr0", "/dev/sr0" }, { "sr1", "/dev/sr1" }, { "sra", "/dev/sra" }, { "srb", "/dev/srb" }, /* next entry indicates end of table */ { 0, 0 }};/* display command usage on standard error and exit */void usage(){ fprintf(stderr, "eject [-f][-u][-v] -- eject default device\n" "eject [-f][-u][-v] <nickname> -- eject device by nickname\n" "eject [-f][-u][-v] <device-name> -- eject device by device name\n" "eject -d -- display default device\n" "eject -n -- display device nicknames\n" "eject -a [on|off|1|0] [-v] -- turn auto-eject feature on or off\n" "\n" "Options:\n" " -f force eject even if device is mounted.\n" " -u unmount before forcing an eject.\n" " -v enables verbose output.\n" ); exit(1);}/* handle command line options */void parse_args(int argc, char **argv){ const char *flags = "fdna:uv"; int c; while ((c = getopt(argc, argv, flags)) != EOF) { switch (c) { case 'f': f_option = 1; break; case 'd': d_option = 1; break; case 'n': n_option = 1; break; case 'a': a_option = 1; /* make some poor guesses at what means on and off */ if (!strcmp(optarg, "0")) a_arg = 0; else if (!strcmp(optarg, "off")) a_arg = 0; else if (!strcmp(optarg, "aus")) a_arg = 0; else if (!strcmp(optarg, "ferme")) a_arg = 0; else if (!strcmp(optarg, "1")) a_arg = 1; else if (!strcmp(optarg, "on")) a_arg = 1; else if (!strcmp(optarg, "auf")) a_arg = 1; else if (!strcmp(optarg, "allumee")) a_arg = 1; else usage(); break; case 'u': u_option = 1; break; case 'v': v_option = 1; break; case '?': usage(); break; } } /* check for a single additional argument */ if ((argc - optind) > 1) usage(); /* too many arguments */ if ((argc - optind) == 1) strcpy(device, argv[optind]); /* one argument */}int main(int argc, char **argv){ int fd; /* file descriptor for CD-ROM device */ int status; /* return status for system calls */ int i; /* loop counter */ char s[255]; /* for error messages */ char s1[256] = { 0 }; /* for reading /etc/mtab */ char s2[256]; /* " " " */ char dummy[256]; /* " " " */ char umount_cmd[256] = "/bin/umount "; /* umount command string */ char *s3; /* general purpose */ FILE *fp; /* for reading /etc/mtab */ /* get default device from $CDROM environment variable; if not set then use compiled in default */ s3 = getenv("CDROM"); if (s3 != NULL) strcpy(default_device, s3); else strcpy(default_device, "/dev/cdrom"); /* make default device the default */ strcpy(device, default_device); /* parse the command line arguments */ parse_args(argc, argv); /* handle -d option */ if (d_option) { printf("eject: default device is `%s'\n", default_device); exit(0); } /* handle -n option */ if (n_option) { printf("eject: device nicknames:\n"); printf("Nickname Device\n"); printf("-------- ----------\n"); for (i = 0 ; nickname[i].name != 0 ; i++) printf("%-8s %-8s\n", nickname[i].name, nickname[i].device); exit(0); } if (v_option) printf("eject: device name is `%s'\n", device); /* check if device is a nickname */ for (i = 0 ; nickname[i].name != 0 ; i++) if (!strcmp(device, nickname[i].name)) { if (v_option) printf("eject: `%s' is a nickname for `%s'\n", device, nickname[i].device); strcpy(device, nickname[i].device); break; } /* check if device is a symbolic link. If so, find out what it points to */ status = readlink(device, s1, sizeof(s1)); if (status != -1) { if (s1[0] == '/') { /* absolute link */ strcpy(s2, s1); } else { /* a relative link */ strcpy(s2, device); s3 = strrchr(s2, '/'); if (s3 != 0) { s3[1] = 0; strcat(s2, s1); } } if (v_option) printf("eject: `%s' is a link to `%s'\n", device, s2); strcpy(device, s2); } /* open device */ fd = open(device, O_RDONLY); if (fd < 0) { sprintf(s, "eject: open failed for `%s'", device); perror(s); exit(1); } /* handle auto-eject option */ if (a_option) {#ifdef CDROMEJECT_SW if (v_option) if (a_arg) printf("eject: enabling auto-eject mode\n"); else printf("eject: disabling auto-eject mode\n"); status = ioctl(fd, CDROMEJECT_SW, a_arg); if (status != 0) { sprintf(s, "eject: CDROMEJECT_SW ioctl failed for `%s'", device); perror(s); exit(1); }#else printf("eject: auto-eject not supported by kernel\n");#endif exit(0); } /* see if device has been mounted by looking in /etc/mtab */ fp = fopen("/etc/mtab", "r"); while (!feof(fp)) { fscanf(fp, "%s %s %s %s %s %s", s1, s2, dummy, dummy, dummy, dummy); if (!strcmp(s1, device)) { if (!f_option) { printf("eject: `%s' is mounted at `%s', not ejected\n", s1, s2); exit(1); } else { if (v_option) printf("eject: `%s' is mounted at `%s'\n", s1, s2); if (u_option) { if (v_option) printf("eject: trying to unmount `%s'\n", s1); strcat(umount_cmd, s1); /* setup umount command */ status = system(umount_cmd); /* do it */ if ((status == -1) || (status == 127)) { sprintf(s, "eject: unmount of `%s' failed", s1); perror(s); } } } break; } } fclose(fp); /* eject */ status = ioctl(fd, CDROMEJECT); if (status != 0) { sprintf(s, "eject: CDROMEJECT ioctl failed for `%s'", device); perror(s); exit(1); } /* close device */ status = close(fd); if (status != 0) { sprintf(s, "eject: close failed for `%s'", device); perror(s); exit(1); } exit(0);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -