kadischi/eject_live_cd eject_live_cd.c,1.2,1.3
Jasper O'neal Hartline (autopsy)
fedora-extras-commits at redhat.com
Wed Jul 12 01:25:09 UTC 2006
Author: autopsy
Update of /cvs/devel/kadischi/eject_live_cd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv1404/kadischi/eject_live_cd
Added Files:
eject_live_cd.c
Log Message:
Smaller eject_live_cd.c
Index: eject_live_cd.c
===================================================================
RCS file: eject_live_cd.c
diff -N eject_live_cd.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ eject_live_cd.c 12 Jul 2006 01:25:07 -0000 1.3
@@ -0,0 +1,526 @@
+/* Build with:
+ diet gcc -static mount_cd.c -lkudzu_loader -lpci_loader -DUSE_DIET -o mount_cd
+*/
+/*
+ *
+ * Modified find_live_cd.c eject.c bits
+ * J. Hartline
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/mount.h>
+#include <kudzu/kudzu.h>
+#include <linux/cdrom.h>
+
+#define IMOUNT_ERR_ERRNO 1
+#define IMOUNT_ERR_OTHER 2
+#define CDDEVICE "/tmp/cdrom"
+
+#ifdef USE_DIET
+char * strcasestr(char * haystack1, char * needle1) {
+ char * haystack = strdup(haystack1);
+ char * needle = strdup(needle1);
+ char * chptr;
+
+ for (chptr = haystack; *chptr; chptr++) *chptr = toupper(*chptr);
+ for (chptr = needle; *chptr; chptr++) *chptr = toupper(*chptr);
+
+ chptr = strstr(needle, haystack);
+ if (!chptr) return NULL;
+
+ return (chptr - haystack) + haystack1;
+}
+#endif
+
+static void
+logMessage (const char *format,
+ ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ vprintf(format, args);
+ va_end (args);
+ printf("\n");
+}
+
+struct devnum {
+ char * name;
+ short major, minor;
+ int isChar;
+};
+
+static struct devnum devices[] = {
+ { "aztcd", 29, 0, 0 },
+ { "pcd", 46, 0, 0 },
+ { "cdu31a", 15, 0, 0 },
+ { "cdu535", 24, 0, 0 },
+ { "cm206cd", 32, 0, 0 },
+ { "fd0", 2, 0, 0 },
+ { "fd1", 2, 1, 0 },
+ { "gscd", 16, 0, 0 },
+ { "input/mouse0", 13, 32, 1 },
+ { "input/mouse1", 13, 33, 1 },
+ { "input/mouse2", 13, 34, 1 },
+ { "input/mouse3", 13, 35, 1 },
+ { "lp0", 6, 0, 1 },
+ { "lp1", 6, 1, 1 },
+ { "lp2", 6, 2, 1 },
+ { "mcd", 23, 0, 0 },
+ { "mcdx", 20, 0, 0 },
+ { "nst0", 9, 128, 1 },
+ { "optcd", 17, 0, 0 },
+ { "psaux", 10, 1, 1 },
+ { "sbpcd", 25, 0, 0 },
+ { "sjcd", 18, 0, 0 },
+ { "ttyS0", 4, 64, 1 },
+ { "ttyS1", 4, 65, 1 },
+ { "ttyS2", 4, 66, 1 },
+ { "ttyS3", 4, 67, 1 },
+};
+
+static int numDevices = sizeof(devices) / sizeof(struct devnum);
+
+static int devMakeInode(char * devName, char * path) {
+ int i;
+ int major, minor;
+ int type;
+ char *ptr;
+ char *dir;
+
+ /* scsi devices sda - sdp: major 8, minor 0 - 255 */
+ /* scsi devices sdq - sdaf: major 65, minor 0 - 255 */
+ /* scsi devices sdqg - sdav: major 66, minor 0 - 255 */
+ /* etc... */
+ if (devName[0] == 's' && devName[1] == 'd') {
+ int drive = 0;
+ char *num = NULL;
+ type = S_IFBLK;
+
+ if (devName[3] && isdigit(devName[3])) {
+ drive = devName[2] - 'a';
+ num = devName + 3;
+ } else if (devName[3] && islower(devName[3])) {
+ drive = ((devName[2] - 'a' + 1) * 26) + devName[3] - 'a';
+ num = devName + 4;
+ } else
+ drive = devName[2] - 'a';
+ /* only 128 SCSI drives, sorry */
+ if (drive > 128)
+ return -1;
+ else if (drive < 16)
+ major = 8;
+ else
+ major = 64 + (drive) / 16;
+ minor = (drive * 16) % 256;
+ if (num && num[0] && num[1])
+ minor += (num[0] - '0') * 10 + (num[1] - '0');
+ else if (num && num[0])
+ minor += (num[0] - '0');
+ if (minor > 255)
+ return -1;
+ } else if (devName[0] == 'm' && devName[1] == 'd') {
+ type = S_IFBLK;
+ major = 9;
+ minor = atoi(devName + 2);
+ } else if (devName[0] == 's' && devName[1] == 'g') {
+ type = S_IFBLK;
+ major = 21;
+ minor = atoi(devName + 2);
+ } else if (!strncmp(devName, "loop", 4)) {
+ type = S_IFBLK;
+ major = 7;
+ minor = atoi(devName + 4);
+ } else if (!strncmp(devName, "scd", 3)) {
+ type = S_IFBLK;
+ major = 11;
+ minor = atoi(devName + 3);
+ } else if (devName[0] == 'h' && devName[1] == 'd') {
+ type = S_IFBLK;
+ if (devName[2] == 'a')
+ major = 3, minor = 0;
+ else if (devName[2] == 'b')
+ major = 3, minor = 64;
+ else if (devName[2] == 'c')
+ major = 22, minor = 0;
+ else if (devName[2] == 'd')
+ major = 22, minor = 64;
+ else if (devName[2] == 'e')
+ major = 33, minor = 0;
+ else if (devName[2] == 'f')
+ major = 33, minor = 64;
+ else if (devName[2] == 'g')
+ major = 34, minor = 0;
+ else if (devName[2] == 'h')
+ major = 34, minor = 64;
+ else if (devName[2] == 'i')
+ major = 56, minor = 0;
+ else if (devName[2] == 'j')
+ major = 56, minor = 64;
+ else if (devName[2] == 'k')
+ major = 57, minor = 0;
+ else if (devName[2] == 'l')
+ major = 57, minor = 64;
+ else if (devName[2] == 'm')
+ major = 88, minor = 0;
+ else if (devName[2] == 'n')
+ major = 88, minor = 64;
+ else if (devName[2] == 'o')
+ major = 89, minor = 0;
+ else if (devName[2] == 'p')
+ major = 89, minor = 64;
+ else if (devName[2] == 'q')
+ major = 90, minor = 0;
+ else if (devName[2] == 'r')
+ major = 90, minor = 64;
+ else if (devName[2] == 's')
+ major = 91, minor = 0;
+ else if (devName[2] == 't')
+ major = 91, minor = 64;
+ else
+ return -1;
+
+ if (devName[3] && devName[4])
+ minor += (devName[3] - '0') * 10 + (devName[4] - '0');
+ else if (devName[3])
+ minor += (devName[3] - '0');
+ } else if (!strncmp(devName, "ram", 3)) {
+ type = S_IFBLK;
+ major = 1;
+ minor = 1;
+ if (devName[3])
+ minor += devName[3] - '1';
+#if defined (__s390__) || defined (__s390x__)
+ } else if (!strncmp(devName, "dasd", 4) && strlen(devName) > 4) {
+ /* IBM Dasd Drives */
+ type = S_IFBLK;
+ major = 94;
+ minor = ( devName[4] - 'a' ) * 4;
+ if (devName[5] && isalpha(devName[5])) {
+ minor += 26 * 4 + ( devName[5] - 'a' ) * 4;
+ if (devName[6] && isdigit(devName[6]) )
+ minor += devName[6] - '0';
+ } else if (devName[5] && isdigit(devName[5])) {
+ minor += devName[5] - '0';
+ }
+ } else if (!strncmp(devName, "mnd", 4)) {
+ /* IBM MiniDisk Drives */
+ type = S_IFBLK;
+ major = 95;
+ minor = devName[3] - 'a';
+#endif
+ } else if (!strncmp(devName, "rd/", 3)) {
+ /* dac 960 "/rd/c0d0{p1}" */
+ int c, d, p;
+ c = d = p = 0;
+ sscanf(devName + 3, "c%dd%dp%d", &c, &d, &p);
+ type = S_IFBLK;
+ major = 48 + c; /* controller */
+ minor = d * 8; /* disk */
+ minor += p; /* partition */
+ } else if (!strncmp(devName, "ida/", 4)) {
+ /* Compaq Smart Array "ida/c0d0{p1} */
+ int c, d, p;
+ c = d = p = 0;
+ sscanf(devName + 4, "c%dd%dp%d", &c, &d, &p);
+ type = S_IFBLK;
+ major = 72 + c; /* controller */
+ minor = d * 16; /* disk */
+ minor += p; /* partition */
+ } else if (!strncmp(devName, "cciss/", 6)) {
+ /* Compaq Smart Array 5300 "cciss/c0d0{p1} */
+ int c, d, p;
+ c = d = p = 0;
+ sscanf(devName + 6, "c%dd%dp%d", &c, &d, &p);
+ type = S_IFBLK;
+ major = 104 + c; /* controller */
+ minor = d * 16; /* disk */
+ minor += p; /* partition */
+ } else if (!strncmp(devName, "ataraid/", 8)) {
+ type = S_IFBLK;
+ major = 114; /* controller */
+ minor = (devName[9] - '0') * 16; /* disk */
+ if (strlen(devName) > 10) /* partition */
+ minor += atoi(devName + 11);
+ } else if (!strncmp(devName, "sx8/", 4)) {
+ /* Promise SX8 "sx8/0{p1} */
+ int d, p;
+ d = p = 0;
+ sscanf(devName + 4, "%dp%d", &d, &p);
+ type = S_IFBLK;
+ major = 160 + (d/8); /* controller */
+ minor = (d % 8) * 32; /* disk */
+ minor += p; /* partition */
+ } else if (!strncmp(devName, "i2o/", 4)) {
+ /* I2O Block Device "i2o/hda */
+ type = S_IFBLK;
+ major = 80; /* controller */
+ minor = (devName[6] - 'a')*16;
+ if ((devName[7]) && isdigit(devName[7]))
+ {
+ minor = minor + atoi(devName + 7);
+ }
+ } else if (!strncmp(devName, "iseries/vcd", 11)) {
+ /* IBM virtual cdrom (iseries) */
+ type = S_IFBLK;
+ major = 113;
+ minor = devName[11] - 'a';
+ } else if (!strncmp(devName, "iseries/vd", 10)) {
+ int drive = 0;
+ char * num = NULL;
+
+ /* IBM virtual disk (iseries) */
+ type = S_IFBLK;
+ major = 112;
+
+ if (devName[11] && isdigit(devName[11])) {
+ drive = devName[10] - 'a';
+ num = devName + 11;
+ } else if (devName[11] && islower(devName[11])) {
+ drive = ((devName[10] - 'a' + 1) * 26) + devName[11] - 'a';
+ num = devName + 12;
+ } else {
+ drive = devName[10] - 'a';
+ }
+
+ minor = (drive * 8);
+ if (num && num[0])
+ minor += (num[0] - '0');
+ } else {
+ for (i = 0; i < numDevices; i++) {
+ if (!strcmp(devices[i].name, devName)) break;
+ }
+ if (i == numDevices) return -1;
+ major = devices[i].major;
+ minor = devices[i].minor;
+
+ if (devices[i].isChar)
+ type = S_IFCHR;
+ else
+ type = S_IFBLK;
+ }
+
+ ptr = path;
+ i = 0;
+ while (*ptr)
+ if (*ptr++ == '/')
+ i++;
+ if (i > 2) {
+ dir = alloca(strlen(path) + 1);
+ strcpy(dir, path);
+ ptr = dir + (strlen(path) - 1);
+ while (*ptr != '/')
+ *ptr-- = '\0';
+ mkdir(dir, 0644);
+ }
+
+ unlink(path);
+ if (mknod(path, type | 0600, makedev(major, minor))) {
+ return -2;
+ }
+
+ return 0;
+}
+
+static int mkdirIfNone(char * directory) {
+ int rc, mkerr;
+ char * chptr;
+
+ /* If the file exists it *better* be a directory -- I'm not going to
+ actually check or anything */
+ if (!access(directory, X_OK)) return 0;
+
+ /* if the path is '/' we get ENOFILE not found" from mkdir, rather
+ then EEXIST which is weird */
+ for (chptr = directory; *chptr; chptr++)
+ if (*chptr != '/') break;
+ if (!*chptr) return 0;
+
+ rc = mkdir(directory, 0755);
+ mkerr = errno;
+
+ if (!rc || mkerr == EEXIST) return 0;
+
+ return IMOUNT_ERR_ERRNO;
+}
+
+
+static int mkdirChain(char * origChain) {
+ char * chain;
+ char * chptr;
+
+ chain = alloca(strlen(origChain) + 1);
+ strcpy(chain, origChain);
+ chptr = chain;
+
+ while ((chptr = strchr(chptr, '/'))) {
+ *chptr = '\0';
+ if (mkdirIfNone(chain)) {
+ *chptr = '/';
+ return IMOUNT_ERR_ERRNO;
+ }
+
+ *chptr = '/';
+ chptr++;
+ }
+
+ if (mkdirIfNone(chain))
+ return IMOUNT_ERR_ERRNO;
+
+ return 0;
+}
+
+
+static int doPwMount(char * dev, char * where, char * fs, int rdonly, int istty,
+ char * acct, char * pw, int bindmnt, int remount) {
+ char * buf = NULL;
+ char * mount_opt = NULL;
+ long int flag;
+ char * chptr __attribute__ ((unused));
+
+
+ /*logMessage("mounting %s on %s as type %s", dev, where, fs);*/
+
+ if (mkdirChain(where))
+ return IMOUNT_ERR_ERRNO;
+
+ if ((*dev == '/' || !strcmp(dev, "none"))) {
+ buf = dev;
+ } else {
+ buf = alloca(200);
+ strcpy(buf, "/tmp/");
+ strcat(buf, dev);
+ }
+ flag = MS_MGC_VAL;
+ if (rdonly)
+ flag |= MS_RDONLY;
+ if (bindmnt)
+ flag |= MS_BIND;
+ if (remount)
+ flag |= MS_REMOUNT;
+
+ if (!strncmp(fs, "vfat", 4))
+ mount_opt="check=relaxed";
+#ifdef __sparc__
+ if (!strncmp(fs, "ufs", 3))
+ mount_opt="ufstype=sun";
+#endif
+
+ /*logMessage("calling mount(%s, %s, %s, %ld, %p)", buf, where, fs,
+ flag, mount_opt);*/
+
+ if (mount(buf, where, fs, flag, mount_opt)) {
+ return IMOUNT_ERR_ERRNO;
+ }
+
+ return 0;
+}
+
+#define LIVECD_FILE ".livecd"
+
+static int setupCdrom(char * location) {
+ int i, rc;
+ char * buf;
+ struct device ** devices = NULL;
+
+ logMessage("probing for CDs");
+ devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, PROBE_LOADED);
+ if (!devices) {
+ logMessage("got to setupCdrom without a CD device");
+ return 0;
+ }
+
+ for (i = 0; devices[i]; i++) {
+ if (!devices[i]->device) continue;
+ logMessage("trying to mount CD device %s", devices[i]->device);
+ devMakeInode(devices[i]->device, "/tmp/cdrom");
+ if (!doPwMount("/tmp/cdrom", location, "iso9660", 1, 0,
+ NULL, NULL, 0, 0)) {
+ char path[1024];
+
+ snprintf(path, sizeof(path), "%s/"LIVECD_FILE, location);
+ if (!access(path, R_OK)) {
+ return 1;
+ }
+
+ /* this wasnt the CD we were looking for, clean up and */
+ /* try the next CD drive */
+ umount(location);
+ unlink("/tmp/cdrom");
+ }
+ }
+ return 0;
+}
+
+
+
+static int EjectCdrom(int fd)
+{
+ int status;
+ int cdrom;
+
+ if (status = ioctl(fd, CDROMEJECT)<0) {
+ perror("ioctl");
+
+ }
+ close(fd);
+ return (status == 0);
+}
+
+
+
+static int OpenDevice()
+{
+ int fd = open(CDDEVICE, O_RDONLY|O_NONBLOCK);
+ if (fd == -1) {
+ exit(1);
+ }
+ return fd;
+}
+
+
+
+
+int main(int argc, char **argv)
+{
+
+ int fd;
+ int worked;
+ char *location = "/mnt/source";
+ int livecd;
+
+
+ if (livecd = setupCdrom(location)) {
+ umount(location);
+ worked = EjectCdrom(fd);
+
+ }
+}
+
+/*
+
+int main (int argc, char *argv[]) {
+ char *location;
+ int res;
+
+ if (argc >= 2) {
+ location = argv[1];
+ } else {
+ location = "/mnt/source";
+ }
+
+ if (setupCdrom (location))
+ return 0;
+ else
+ return 1;
+}
+
+*/
More information about the fedora-extras-commits
mailing list