summaryrefslogtreecommitdiff
path: root/vms/ldrset.c
diff options
context:
space:
mode:
Diffstat (limited to 'vms/ldrset.c')
-rw-r--r--vms/ldrset.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/vms/ldrset.c b/vms/ldrset.c
new file mode 100644
index 0000000..c0efd0c
--- /dev/null
+++ b/vms/ldrset.c
@@ -0,0 +1,183 @@
+/* LDRSET - Set the state of the LDR flag in UCB$L_DEVCHAR2 for a
+** SCSI magtape. REQUIRES CMKRNL privilege.
+**
+** Copyright 1999 by TECSys Development, Inc. http://www.tditx.com
+**
+** This program is free software; you may redistribute and/or modify it under
+** the terms of the GNU General Public License Version 2 as published by the
+** Free Software Foundation.
+**
+** 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 complete details.
+**
+** Description:
+** This is a small KERNEL MODE utility program to go set or reset
+** the DEV$M_LDR flag in UCB$L_DEVCHAR2 for a specified device. While
+** a certain amount of checking is performed, and while the author
+** believes that this utility is safe, ONLY YOU can make that
+** determination with respect to your environment. There are NO
+** GUARANTEES WHATSOEVER that use of this program will not CRASH
+** YOUR SYSTEM or worse. TDI disclaims any responsibility for any
+** losses or damages from the use of this program.
+**
+** With all that said... this utility can be used [example: system
+** startup] to set the LDR flag for the autoloader tape device.
+** With the loader flag properly set, you can re-enable the LDR
+** check section in MTX and be fairly well certain that the MTX
+** utility will not be used against a drive that is not a SCSI
+** MAGTAPE with a LOADER attached.
+**
+**
+** LDRSET.CLD:
+** define verb LDRSET
+** image sys$disk:[]ldrset.exe
+** parameter p1, label=device,
+** prompt="Device",
+** value(required,type=$FILE)
+** qualifier SET, nonnegatable
+** qualifier RESET, nonnegatable
+** disallow any2 (SET, RESET)
+** disallow NOT SET AND NOT RESET
+*/
+#ifdef __DECC
+#pragma module LDRSET "V01-00"
+#else
+#module LDRSET "V01-00"
+#endif
+
+#include <ssdef.h>
+#include <dcdef.h>
+#include <devdef.h>
+#include <dvidef.h>
+#include <descrip.h>
+#include <stdio.h>
+#include <string.h>
+#include <lib$routines.h>
+#include <starlet.h>
+
+#ifndef DESCR_CNT
+#define DESCR_CNT 16
+/* MUST BE of the form 2^N!, big enough for max concurrent usage */
+#endif
+
+static struct dsc$descriptor_s *
+descr(
+ char *str)
+{
+static struct dsc$descriptor_s d_descrtbl[DESCR_CNT]; /* MAX usage! */
+static unsigned short int descridx=0;
+ struct dsc$descriptor_s *d_ret = &d_descrtbl[descridx];
+
+ descridx = (descridx+1)&(DESCR_CNT-1);
+
+ d_ret->dsc$w_length = strlen((const char *)str);
+ d_ret->dsc$a_pointer = (char *)str;
+
+ d_ret->dsc$b_class =
+ d_ret->dsc$b_dtype = 0;
+ return(d_ret);
+}
+
+extern unsigned long int finducb();
+extern unsigned long int _setldr();
+extern unsigned long int _clrldr();
+
+unsigned long int
+set_ldrstate(
+ int devch,
+ int setstate)
+{
+ unsigned long int ret;
+ struct ucbdef *ucb;
+
+ if (~(ret=finducb(devch,&ucb))&1)
+ return(ret);
+
+ if (setstate)
+ return(_setldr(ucb));
+ else
+ return(_clrldr(ucb));
+}
+
+extern unsigned long int CLI$PRESENT();
+extern unsigned long int CLI$GET_VALUE();
+
+static unsigned long int
+cld_special(
+ char *kwd_name)
+{
+ lib$establish(lib$sig_to_ret);
+ return(CLI$PRESENT(descr(kwd_name)));
+}
+
+int
+main(){
+ unsigned long int ret;
+ unsigned long int ismnt = 0;
+ unsigned long int dvcls = 0;
+ unsigned long int dchr2 = 0;
+ struct itmlst_3 {
+ unsigned short int ilen;
+ unsigned short int code;
+ unsigned long int *returnP;
+ unsigned long int ignored;
+ } dvi_itmlst[] = {
+ {4, DVI$_MNT, 0/*&ismnt*/, 0},
+ {4, DVI$_DEVCLASS, 0/*&dvcls*/, 0},
+ {4, DVI$_DEVCHAR2, 0/*&dchr2*/, 0},
+ {0,0,0,0} };
+ unsigned long int iosb[2];
+ struct dsc$descriptor_s *dp_tmp;
+ struct dsc$descriptor_d dy_devn = { 0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0 };
+ unsigned long int devch=0;
+
+ dvi_itmlst[0].returnP = &ismnt;
+ dvi_itmlst[1].returnP = &dvcls;
+ dvi_itmlst[2].returnP = &dchr2;
+
+ if (~(ret=CLI$PRESENT(dp_tmp=descr("DEVICE")))&1) {
+ printf("?Error obtaining CLD DEVICE parameter\n");
+ return(ret); }
+ if (~(ret=CLI$GET_VALUE(dp_tmp,&dy_devn,0))&1) {
+ printf("?Error obtaining CLD DEVICE value\n");
+ return(ret); }
+
+ if (~(ret=sys$alloc(&dy_devn,0,0,0,0))&1) {
+ printf("?Error allocating specified device\n");
+ return(ret); }
+
+ if (~(ret=sys$assign(&dy_devn,&devch,0,0))&1) {
+ printf("?Error assigning a channel to specified device\n");
+ return(ret); }
+
+ if (~(ret=sys$getdviw(0,devch,0,&dvi_itmlst,&iosb,0,0,0))&1) {
+ printf("?Error obtaining device information(1)\n");
+ return(ret); }
+ if (~(ret=iosb[0])&1) {
+ printf("?Error obtaining device information(2)\n");
+ return(ret); }
+
+ if (dvcls != DC$_TAPE) {
+ printf("?Device is not a tape drive\n");
+ return(SS$_IVDEVNAM); }
+
+ if (~dchr2 & DEV$M_SCSI) {
+ printf("?Device is not a SCSI device\n");
+ return(SS$_IVDEVNAM); }
+
+ if (ismnt) {
+ printf("?Device is mounted\n");
+ return(SS$_DEVMOUNT); }
+
+ if (cld_special("SET")&1)
+ return(set_ldrstate(devch,1));
+
+ if (cld_special("RESET")&1)
+ return(set_ldrstate(devch,0));
+
+ /* Either SET or RESET above must be present to win */
+ printf("?CLD structural error - see source\n");
+ return(SS$_BADPARAM);
+}