Comment ======================================================== Copyright 1990 by Marc Perkel * All right reserved. MarxMenu now allows you to login to a Novell network without using Novell's login program or messing with nasty login scripts. You can be in MarxMenu all the way in. Logging into Novell is tricky. Especially if you are using boot roms on your network cards. Through much trial and error, I have found some solid tricks that make life easier. You should have the following two BATCH files in your LOGIN directory as follows: LOADNET.BAT ----------- NETX F: STARTUP STARTUP.BAT ----------- SET BOOTUP=LOGIN MarxMenu Login %BOOTUP% Each workstation should have their own AUTOEXEC.BAT. The last line should be LOADNET. If you are running multiple versions of dos you can have the first line of LOADNET.BAT be %NET%. You will then have to have SET NET=NETX in your AUTOEXEC.BAT file. Also, if you want automatic login you can add the following lines: SET USERNAME=MARC Your Name Here SET PASSWORD=NERD Your Password Here You should also change the COMSPEC= to the network command.com BEFORE you run NETX. For some unknown reason, this solves a lot of problems. Example: IPX SET COMSPEC=O:COMMAMD.COM NETX Another boot rom quirk is that you can't run any program off a boot rom that trashes upper memory. An example is running QEMM on a monochrome monitor. By using this method the boot disk or boot rom hands control over in a clean way. LOADNET.BAT then branches to STARTUP.BAT for the rest of the login sequence. For some strange reason which I can't explain, LOADNET and STARTUP have to be two separate batch files. I think it forces the transient part of COMMAND.COM to load into memory. Anyhow, don't combine these into one batch file The first line of STARTUP.BAT is a message that tells this menu that the user is logging in for the first time. This menu creates a batch file and puts the name of it in the environment variable BOOTUP. STARTUP.BAT then executes this file. This is the example for MY network. You'll have to modify it for yours. One word of caution. After modifing this menu, always run MARXCOMP LOGIN to compile it. Otherwise, if you boot up into it you won't have enough access rights to recompile automatically. ======================================================== EndComment var UserName OldPass NewPass Logged Station NetAddress SmartDir MyServer OrigServer HomeDir DosDir BatName BatFile UseMarxLogin Shell PasswordExpDays SkipError Servers StatusWin Comment ======================================================== If UseMarxLogin is set to true then this program will use the MarxMenu API call to log into the network. If set to false the it will shell Novell's LOGIN.EXE program. If UseMarxLogin is set to true, and you are using 386 NetWare then you will have to add the following command to your AUTOEXEC.NCF file: SET ALLOW UNENCRYPTED PASSWORDS = ON ======================================================== EndComment UseMarxLogin = True Shell = CleanFileName(ReadEnv('COMSPEC')) MyServer = NovDefaultServer OrigServer = MyServer NovServers(Servers) Logged = ReadEnv('LOGGED') = 'TRUE' Comment ======================================================== If Environment variables USERNAME and PASSWORD are set, this menu will attempt to log into the network using these values. This allows for automatic login. You can also pass the parameters on the command line as follows. MarxMenu Login The name may contain a referrence to a server: Server/Name ======================================================== EndComment ;----- If CapsLock key is on then override default login SkipError = False if not Logged if CapsLock CapsLock Off else UserName = ParamStr(2) if UserName = '' then UserName = ReadEnv('USERNAME') if UserName > '' OldPass = ParamStr(3) if OldPass = '' then OldPass = ReadEnv('PASSWORD') if OldPass > '' SkipError = True Login (UserName,OldPass) SkipError = False if PasswordNeedsChanged Logged = False Suggest 'C' endif endif endif endif endif if not Logged LoginFromScreen endif NovSetPrimaryServer (MyServer) NovSetPreferredServer (MyServer) UserName = NovMyLoginName SetEnv ('NET=') SetEnv ('LOGGED=') SetEnv ('USERNAME=' + UserName) SetEnv ('PASSWORD=') ;----- Another Server Selected if MyServer <> OrigServer SetEnv ('BOOTUP=STARTUP') SetEnv ('LOGGED=TRUE') NovMapDrive('F',MyServer + '/SYS:LOGIN') ChDir('F:\LOGIN') ExitMenu endif Comment ======================================================== Here we set a different directory for a program depending on if we have a color or monochrome monitor. ======================================================== EndComment if VideoMode = Mono SmartDir = 'F:\PUBLIC\MSMART' else SmartDir = 'F:\PUBLIC\CSMART' endif ;----- You can't assume that you have an F: drive unless you map it. NovMapDrive ('F','SYS:\LOGIN') ;----- Here we calculate a home directory for each user. HomeDir = 'F:\HOME\' + UserName if UserName = 'SUPERVISOR' then HomeDir = 'F:\SYSTEM' if not ExistDir(HomeDir) then HomeDir = 'F:\PUBLIC\UTIL' Comment ======================================================== Here we calulate the the name of the dos directory that matches the version of dos we are running. The directory for DOS 5.0 would be F:\PUBLIC\DOSV5.00 ======================================================== EndComment DosDir = 'F:\PUBLIC\DOSV' + DosVersionString ;----- DR DOS if ReadEnv('OS') > '' DosDir = 'F:\PUBLIC\' + ReadEnv('OS') + ReadEnv('VER') endif Comment ======================================================== Here's where we map our drives. This does not set the search path. You set that explicitly by writing to the PATH environment variable. Drive map commands may contain server and volume referrences: ======================================================== EndComment NovMapRoot ('H', HomeDir) ;Home Directory NovMapRoot ('N','F:\PUBLIC\NSK') ;Network Survival Kit NovMapRoot ('O', DosDir) ;Dos Directory NovMapRoot ('U','F:\PUBLIC\UTIL') ;Utilities Directory NovMapRoot ('P','F:\PUBLIC') ;Public Directory NovMapRoot ('L','F:\LOGIN') if NovConsoleOperator NovMapRoot ('V','F:\SYSTEM') ;System Directory endif if MyServer = 'TYME' NovMapDrive ('I','VOL1:') ;----- Here's where I log into a second server. if PosInList('TYME2',Servers) > 0 NovLogin('TYME2/' + UserName,OldPass) NovMapDrive('K','TYME2/SYS:') endif ;----- Here's where I log into a third server. if PosInList('TSS',Servers) > 0 NovLogin('TSS/' + UserName,OldPass) NovMapDrive('J','TSS/SYS:') endif endif if ExistDir SmartDir NovMapRoot ('S',SmartDir) endif ;----- Turbo Pascal 6 if ExistDir (HomeDir + '\TP6') then NovMapRoot ('T',HomeDir + '\TP6') ;----- Windows fake root is W: if ExistDir (HomeDir + '\WIN') then NovMapRoot ('W',HomeDir + '\WIN') ;----- If no drive C then use home directory if not ExistDir ('C:\') then NovMapRoot('C','H:') ;----- Here we define our search paths. SetEnv ('PATH=T:\;H:\;U:\;N:\;O:\;P:\;V:\;S:\;') FixPath ;Verifies all search paths exist ChDir (HomeDir) ;----- Here's where we set master environment variable strings SetEnv ('STATION=' + Station) if Left(Shell,2) <> 'C:' then SetEnv ('COMSPEC=O:\COMMAND.COM') SetEnv ('PROMPT=$e[1;33m$p: $e[0;32m') SetEnv ('MXECHO=OFF') if UserName <> 'MARC' SetEnv ('PD.EXE=/$F:\HOME\PD.PIC') else SetEnv ('PD.EXE=/$H:\PD.PIC') endif Comment ======================================================== If a TEMP environment variable is set, MarxMenu will use it for temporary batch files. This is compatible with DOS 5 and Windows conventions. The users should be given full access rights to this directory. I'm using \TMPFILES for my network. ======================================================== EndComment if ExistDir('\TMPFILES') then SetEnv('TEMP=' + CleanFileName('\TMPFILES')) Comment ======================================================== Opens a semaphore that XMETER can read. To see how many users are users are on with XMETER type: XMETER LOGIN /U ======================================================== EndComment NovOpenSemaphore ('XM-LOGIN',0) ;----- Turn NumLock key on if in NumLock group. if NovInGroup('NUMLOCK') NumLock On else NumLock Off endif ;----- LOGIN is set to BOOTUP if logging in for the first time if UpperCase(ReadEnv('BOOTUP')) <> 'LOGN' then ExitMenu Comment ======================================================== In order to load TSRs, MarxMenu writes a temporary batch file and exits. The STARTUP.BAT file then jumps to this batch file. ======================================================== EndComment ;----- Create temporary batch file for rest of login sequence BatName = 'H:' + NamePart(BatFileName) + '.BAT' SetEnv ('BOOTUP=' + BatName) FileAssign(BatFile,BatName) FileCreate(BatFile) ;----- To debug, set ECHO ON and add PAUSE commands if DosVersionString < '3.30' WriteBat('ECHO OFF') else WriteBat('@ECHO OFF') endif WriteBat ('SET BOOTUP=') ;WriteBat ('MARK > NUL') if UserName <> 'CLEAN' then WriteBat ('CASTAWAY /W=0 /I=0') ;----- Load Lan Assist if NovInGroup ('LANASSIST') WriteBat ('F:\PUBLIC\QEMM\LOADHI P:LA\LA +N >NUL') endif Comment ================================================================ This next section deals with running special programs bases on the physical station number rather than by user. This deals with special hardware that needs software drivers loaded. ================================================================ EndComment ;----- CD ROM Machine ;if NetAddress = '255:2' ; WriteBat ('CD\PUBLIC\MA') ; WriteBat ('MSCDEX.EXE /D:MSCD003 /M:12') ; WriteBat ('MAR C:\ RW=/ /C') ;endif ;----- Vicki's Printer if NetAddress = '255:65' ; WriteBat('P:PA\PA P=1 M=200 T=10 Q1=TYME/VICKI') ; Capture('VICKI',1) endif ;----- Grace's Printer if NetAddress = '255:68' ; WriteBat('P:PA\PA P=1 M=200 T=10 Q1=TYME/GRACE') ; Capture('GRACE',1) endif ;----- Nita's Printer if NetAddress = '255:E8' ; WriteBat('P:PA\PA P=1 M=200 T=10 Q1=TYME/NITA') ; Capture('NITA',1) endif if (NetAddress = '255:C3') or (NetAddress = '254:C3') WriteBat('MODE BW80') endif Comment ================================================================ This next section deals with running special programs bases on the users preferrences. ================================================================ EndComment if UserName = 'MARC' WriteBat('KBD 6 NumOff'); Capture('DOT',1) Capture('LASER',2) ChDir('TP6') endif if UserName = 'VICKI' Capture('LASER',2) WriteBat('KBD 6'); WriteBat('MOUSE') endif if UserName = 'KEVIN' WriteBat('KBD 0,0 NumOn'); Capture('LASER',1) Capture('DOT',2) SetEnv('PROMPT=($p)') SetEnv('PATH=' + ReadEnv( 'Path' ) + ';f:\home\kevin\brief' ) ChDir('MARX') endif if UserName = '386' WriteBat('KBD 6 NumOff'); Capture('DOT',1) Capture('LASER',2) endif if UserName = 'TBBS' Capture('DOT',1) Capture('LASER',2) ChDir('I:\BBS\TBBS') NovMapDrive('H','I:') SetEnv('D.EXE=/O/I') WriteBat('CASTOFF') WriteBat('DROPTO ' + BatName + ' R1') endif if UserName = 'GRACE' WriteBat('KBD 6 NumOn'); Capture('LASER',2) endif if UserName = 'NITA' WriteBat('KBD 6 NumOn CapsOn'); Capture('LASER',2) endif if UserName = 'WORK' WriteBat('KBD 6 NumOff'); Capture('DOT',1) Capture('LASER',2) endif ;----- Load SideKick if in Sidekick Group if NovInGroup 'SIDEKICK' WriteBat ('KBD CR') WriteBat ('F:\PUBLIC\QEMM\LOADHI SWAPSK/N/G/D' + HomeDir + ' >NUL') WriteBat ('SK') WriteBat ('CLS') endif ;----- Load SideKick 2 if in SK2 Group if NovInGroup 'SK2' WriteBat ('CD SK2') WriteBat ('SK2') WriteBat ('CD ..') endif Comment ================================================================ The batch file ends by jumping to personal menu, if there is one, or the default menu if there isn't. DROPTO.BAT is used to erase the temporary batch file that this menu creates. ================================================================ EndComment if ExistFile ('F:\HOME\' + UserName + '\' + UserName + '.MNU') WriteBat ('DROPTO ' + BatName + ' MARX ' + UserName) endif WriteBat ('DROPTO ' + BatName + ' MARX TYME') FileClose(BatFile) ExitMenu ;=============================================================== ;----- Procedure Definitions Procedure WriteBat (BatLine) FileWriteln(BatFile,BatLine) EndProc Procedure Pause WriteBat ('PAUSE') EndProc Procedure Capture (Queue, PrinterPort) var PortSt PortSt = Str(PrinterPort) WriteBat ('P:CAPTURE Q=' + Queue + ' C=1 NB NFF TI=5 L=' + PortSt + '>NUL') EndProc ;----- Select colors and prepare screen Procedure LoginFromScreen if ColorScreen TextColor White Red BoxBorderColor Green Brown BoxInsideColor Black Brown ClearScreen 176 ClockColor Black Brown TextColor Black Green BoxHeaderColor Yellow Mag Shadow else TextColor Grey Black ClearScreen 176 TextColor Black Grey BoxBorderColor Black Grey BoxInsideColor Black Grey BoxHeaderColor Black Grey ClockColor Black Grey endif BlankMessage = 'Netware Login' ClockMode = 262 GotoXY 1 25 ClearLine WriteCenter "Computer Tyme Master Network Login Menu" SingleLineBox Explode Off ShadowColor Grey Red if ColorScreen DrawBox 3 2 74 5 ClockPos 42 5 TextColor Blue Brown else DrawBox 3 2 76 5 ClockPos 44 5 endif WriteCenter 'Computer Tyme Software Development Laboratory' Writeln TextColor Black Brown WriteCenter '컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴�' Writeln TextColor Black Brown Write " (C) 1990 by Marc Perkel" DoubleLineBox BlankTime = 10 Explode On BlockBox BoxBorderColor Green Blue BoxInsideColor Yellow Blue BoxHeader = " Station Information " if ColorScreen DrawBox 39 17 38 6 TextColor Yellow Blue else DrawBox 41 17 38 6 TextColor Grey Black endif StatusWin = CurrentWindow UpdateStatusWindow ChooseOption EraseTopWindow EraseTopWindow EraseTopWindow TextColor Grey Black ClearScreen EndProc Procedure ChooseOption var Ch X repeat X = 4 if NumberOfElements(Servers) > 1 then X = 5 DrawBox 3 17 26 X UseArrows OnScreenOnly InverseColor Yellow Cyan Writeln ' L - Login to Network' Write ' C - Change Password' if NumberOfElements(Servers) > 1 Writeln Write ' S - Select Server' endif Ch = UpperCase(ReadKey) if (Ch = 'L') or (Ch = 'C') or (Ch = 'S') EraseTopWindow if Ch = 'L' LoginToNetwork (False) endif if Ch = 'C' LoginToNetwork (True) endif if Ch = 'S' SelectServer endif endif until Logged EndProc Procedure Warning (St) BoxHeader ' Warning ' DrawBox 3 17 length(St) + 4 3 Write Char(7) ' ' St Wait 300 EraseTopWindow EndProc Procedure LoginToNetwork (CP) var NewPassVerify BoxHeader = ' Logging into Server * ' + MyServer + ' ' DrawBox 3 10 50 4 UseArrows Off Security repeat if UserName = '' Write ' Name: ' UserName = UpperCase(Readln) Writeln endif Write ' Password: ' OldPass = UpperCase(Readln) Write CR ClearLine Login (UserName,OldPass) if not CP CP = PasswordNeedsChanged if CP then Warning('Time to change your password!') endif if CP if LastKey <> Esc repeat Write ' New Password: ' NewPass = UpperCase(Readln) Write CR ClearLine if NewPass = OldPass then Warning('Select a NEW Password!') until NewPass <> OldPass endif if LastKey <> Esc Write ' Verify: ' NewPassVerify = UpperCase(Readln) Write CR ClearLine if NewPass = NewPassVerify NovChangePassword (OldPass,NewPass) if NovResult <> 0 Warning ('Password Change Failed!') Logged = False endif else Warning('Password Typed Wrong!') Logged = False endif endif endif ClearScreen if not Logged UserName = '' endif until (LastKey = Esc) or Logged EraseTopWindow EndProc Procedure Login (User, Pass) if UseMarxLogin NovLogin (MyServer + '/' + User, Pass) if NovResult = 223 then NovResult = 0 ;grace login Logged = NovResult = 0 if Logged NovMapDrive('F',MyServer + '/SYS:LOGIN') endif else ClearScreenFirst Off UseCommand On StuffKbd = Pass + CR Execute ('LOGIN.EXE ' + MyServer + '/' + User + '>nul') Logged = ExistDir ('F:\SYSTEM') endif if not Logged and not SkipError if NovResult = 254 Warning('All Logins Disabled!') else if NovResult = 222 Warning('Password Expired!') else if NovResult = 220 Warning('Account Disabled!') else if (NovResult = 218) or (NovResult = 219) Warning('Invalid Login Time!') else if NovResult = 197 Warning('Intruder Lockout!') else if NovResult = 255 Warning('Bad Password!') else Warning('Login Failed! '+ Str(NovResult)) endif endif endif endif endif endif endif EndProc Procedure PasswordNeedsChanged var X X = NovPasswordExpDate (UserName) if X = 0 then Return False Return (X - Today) / SecondsInDay <= 5 EndProc Procedure SelectServer DrawBox 25 9 20 NumberOfElements (Servers) + 2 MyServer = PickOne (Servers) NovSetPrimaryServer (MyServer) NovSetPreferredServer (MyServer) EraseTopWindow UpdateStatusWindow EndProc Procedure UpdateStatusWindow SetTopWindow StatusWin ClearScreen NetAddress = NovStationAddress (NovConnection) Station = Str(NovConnection) while length(Station) < 3 Station = '0' + Station endwhile Writeln ' Server: ' MyServer Writeln ' Network: ' NetAddress Writeln ' Connection: ' Station Write ' DOS Version: ' DosVersionString if StatusWin <> CurrentWindow SetWindowUnder (StatusWin,StatusWin + 1) endif EndProc Procedure AfterHours Return (DayOfWeek = Sun) or (DayOfWeek = Sat) or (Hour > 18) or (Hour < 5) EndProc ;----- Show Item for Debugging Procedure ShowMe (Item) DrawBox 1 23 80 3 Write ' ' TextColor Yellow Cyan Write Item Wait 300 EraseTopWindow EndProc ;ShowItem