Imported Upstream version 1.3.11
[debian/mtx] / scsieject.c
diff --git a/scsieject.c b/scsieject.c
new file mode 100644 (file)
index 0000000..7943035
--- /dev/null
@@ -0,0 +1,255 @@
+/* Copyright 2007, Robert Nelson\r
+ *   Released under terms of the GNU General Public License as\r
+ * required by the license on 'mtxl.c'.\r
+ * $Date: 2007-01-28 19:23:33 -0800 (Sun, 28 Jan 2007) $\r
+ * $Revision: 125 $\r
+ */\r
+\r
+/* This is a generic SCSI device control program. It operates by\r
+ * directly sending commands to the device.\r
+ */\r
+\r
+/* \r
+ *     Commands:\r
+ *             load -- Load medium\r
+ *             unload -- Unload medium\r
+ *             start -- Start device\r
+ *             stop -- Stop device\r
+ *             lock -- Lock medium\r
+ *             unlock -- Unlock medium\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "mtx.h"\r
+#include "mtxl.h"\r
+\r
+#if HAVE_UNISTD_H\r
+#include <unistd.h>\r
+#endif\r
+\r
+#if HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+\r
+#ifdef _MSC_VER\r
+#include <io.h>\r
+#endif\r
+\r
+char *argv0;\r
+\r
+/* the device handle we're operating upon. */\r
+static char *device;  /* the device name. */\r
+static DEVICE_TYPE DeviceFD = (DEVICE_TYPE) -1;\r
+\r
+static int S_load(void);\r
+static int S_unload(void);\r
+static int S_start(void);\r
+static int S_stop(void);\r
+static int S_lock(void);\r
+static int S_unlock(void);\r
+\r
+struct command_table_struct\r
+{\r
+       char *name;\r
+       int (*command)(void);\r
+}\r
+       command_table[] =\r
+{\r
+       { "load", S_load },\r
+       { "unload", S_unload },\r
+       { "start", S_start },\r
+       { "stop", S_stop },\r
+       { "lock", S_lock },\r
+       { "unlock", S_unlock },\r
+       { NULL, NULL } /* terminate list */\r
+};\r
+\r
+void Usage(void)\r
+{\r
+       FatalError("Usage: scsieject -f <generic-device> <command> where <command> is:\n load | unload | start | stop | lock | unlock\n");\r
+}\r
+\r
+/* open_device() -- set the 'DeviceFD' variable.... */\r
+void open_device(void)\r
+{\r
+       if (DeviceFD != -1)\r
+       {\r
+               SCSI_CloseDevice("Unknown", DeviceFD);\r
+       }\r
+\r
+       DeviceFD = SCSI_OpenDevice(device);\r
+}\r
+\r
+/* we see if we've got a file open. If not, we open one :-(. Then\r
+ * we execute the actual command. Or not :-(. \r
+ */ \r
+int execute_command(struct command_table_struct *command)\r
+{\r
+       /*\r
+        * If the device is not already open, then open it from the \r
+        * environment.\r
+        */\r
+       if (DeviceFD == -1)\r
+       {\r
+               /* try to get it from STAPE or TAPE environment variable... */\r
+               if ((device = getenv("STAPE")) == NULL &&\r
+                       (device = getenv("TAPE")) == NULL)\r
+               {\r
+                       Usage();        /* Doesn't return */\r
+               }\r
+\r
+               open_device();\r
+       }\r
+\r
+       /* okay, now to execute the command... */\r
+       return command->command();\r
+}\r
+\r
+\r
+/* parse_args():\r
+ * Basically, we are parsing argv/argc. We can have multiple commands\r
+ * on a line, such as "load start" to load a tape and start the device.\r
+ * We execute these commands one at a time as we come to them. If we don't \r
+ * have a -f at the start and the default device isn't defined in a TAPE or \r
+ * STAPE environment variable, we exit.\r
+ */ \r
+\r
+int parse_args(int argc, char **argv)\r
+{\r
+       int index, retval;\r
+       struct command_table_struct *command;\r
+\r
+       argv0 = argv[0];\r
+\r
+       for (index = 1; index < argc; index++)\r
+       {\r
+               if (strcmp(argv[index], "-f") == 0)\r
+               {\r
+                       index++;\r
+                       if (index >= argc)\r
+                       {\r
+                               Usage();        /* Doesn't return */\r
+                       }\r
+                       device = argv[index];\r
+                       open_device();\r
+               }\r
+               else\r
+               {\r
+                       for (command = &command_table[0]; command->name != NULL; command++)\r
+                       {\r
+                               if (strcmp(command->name, argv[index]) == 0)\r
+                               {\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       if (command->name == NULL)\r
+                       {\r
+                               Usage();        /* Doesn't return */\r
+                       }\r
+\r
+                       retval = execute_command(command);\r
+\r
+                       if (retval < 0)\r
+                       {\r
+                               /* Command failed, we probably shouldn't continue */\r
+                               return retval;\r
+                       }\r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+int S_load(void)\r
+{\r
+       int result = LoadUnload(DeviceFD, 1);\r
+\r
+       if (result < 0)\r
+       {\r
+               fputs("scsieject: load failed\n", stderr);\r
+               fflush(stderr);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+int S_unload(void)\r
+{\r
+       int result = LoadUnload(DeviceFD, 0);\r
+\r
+       if (result < 0)\r
+       {\r
+               fputs("scsieject: unload failed\n", stderr);\r
+               fflush(stderr);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+int S_start(void)\r
+{\r
+       int result = StartStop(DeviceFD, 1);\r
+\r
+       if (result < 0)\r
+       {\r
+               fputs("scsieject: start failed\n", stderr);\r
+               fflush(stderr);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+int S_stop(void)\r
+{\r
+       int result = StartStop(DeviceFD, 0);\r
+\r
+       if (result < 0)\r
+       {\r
+               fputs("scsieject: stop failed\n", stderr);\r
+               fflush(stderr);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+int S_lock(void)\r
+{\r
+       int result = LockUnlock(DeviceFD, 1);\r
+\r
+       if (result < 0)\r
+       {\r
+               fputs("scsieject: lock failed\n", stderr);\r
+               fflush(stderr);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+int S_unlock(void)\r
+{\r
+       int result = LockUnlock(DeviceFD, 0);\r
+\r
+       if (result < 0)\r
+       {\r
+               fputs("scsieject: unlock failed\n", stderr);\r
+               fflush(stderr);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+/* See parse_args for the scoop. parse_args does all. */\r
+int main(int argc, char **argv)\r
+{\r
+       parse_args(argc, argv);\r
+\r
+       if (device)\r
+       {\r
+               SCSI_CloseDevice(device, DeviceFD);\r
+       }\r
+\r
+       exit(0);\r
+}\r