1. setting environment variables
- Posted by Jacques Deschenes <desja at QUEBECTEL.COM> Nov 30, 1996
- 1637 views
--=====================_849413188==_ A few days ago someone ask a question about setting environment variable. I lost that message, anyway here is a demo that demontrate the use of parent environment to transfert information between parent and child process. This technic can be use to build a batch extender. This demo program can be used in a batch file to split file name and extension . For more information see note at beginning of demo. --=====================_849413188==_ -- November 30th, 1996 -- Environment demo -- By Jacques Deschenes -- -- EnvDemo demonstrate how to use environment of parent process to establish -- data transfert between a parent and child process -- this technic is used by some batch extender program. -- The batch extender program is running as a child process of command.com -- it's environment is erased when it terminate. -- So if it modify it's own environment the parent won't see it. -- The batch extender should write it's functions results in the parent -- environment. -- This demo program will read a variable in named FILE in parent envrionment -- and split name and extension and return the result in NAME and EXT environ- -- ment variables. -- -- Exemple of use: -- write a batch file name SPLIT.BAT like the following -- -- REM SPLIT FILE NAME AND EXTENSION -- SET -- SET FILE=%1 -- ex envdemo -- echo name is %NAME% -- echo extension is %EXT% -- SET FILE= -- SET NAME= -- SET EXT= -- -- NOTE: parent environment should have enough space to create the new -- variables. -- this demo could be use as a foundation to build batch extender. -- with trace include machine.e atom EnvAddr integer EnvSize, EnvFree function UpCase(integer a) if a >= 'a' and a <= 'z' then return a - 'a' + 'A' else return a end if end function -- UpCase() function GetParentEnv() -- return address of parent process environment sequence r atom psp -- program segment prefix atom Parentpsp -- address of parent psp atom ParentEnv -- in DOS each process has a psp and a copy of environment -- Get PSP segment address r = repeat(0,10) r[REG_AX] = #6200 -- dos call function #62 = get current PSP r = dos_interrupt(#21,r) -- return psp segment address in BX psp = r[REG_BX]*16 -- convert segment to linear address -- get parent process psp address, this is at offset #16 in psp Parentpsp = 16*(peek(psp+#16)+peek(psp+#17)*256) -- get parent process environment address, this is at offset #2C in PSP ParentEnv = 16*(peek(Parentpsp+#2C)+peek(Parentpsp+#2D)*256) return ParentEnv end function -- GetParentEnv() function SeekEOS() -- return offset of end of string integer zero, i, char i = 0 zero = 0 while 1 do char = peek(EnvAddr+i) if char = 0 then if zero then exit else zero = 1 end if else zero = 0 end if i = i + 1 end while return i end function -- SeekEOS() function ReadASCIIZ(integer ofs) -- return a string from environment -- input: ofs is offset to start reading from. -- output: string without the zero integer char sequence str str = {} while 1 do char = peek(EnvAddr+ofs) if char = 0 then exit else str = str & char end if ofs = ofs + 1 end while return str end function -- ReadASCIIZ() function GetVar(sequence Name) -- return the value of an environment variable -- input: name is variable name -- EnvAddr is environment address. -- ouput: variable value if found or {} if not found integer i sequence str,left -- trace(1) i = 0 while 1 do str = ReadASCIIZ(i) if length(str) = 0 then return {} end if left = str[1..find('=',str)-1] if compare(left,Name) = 0 then return str[find('=',str)+1..length(str)] end if i = i + length(str) + 1 end while end function --GetVar() procedure EraseVar(sequence Name) -- erase an environment variable -- input: EnvAddr is address environment -- Name is name of variable to erase integer i,j, char, zero sequence str,left i = 0 while 1 do str = ReadASCIIZ(i) if length(str) = 0 then return end if left = str[1..find('=',str)-1] if compare(left,Name) = 0 then zero = 1 j = i + length(str)+1 while 1 do -- variable found, erase it. char = peek(EnvAddr+j) poke(EnvAddr+i,char) if char = 0 then if zero then exit else zero = 1 end if else zero = 0 end if i = i + 1 j = j + 1 end while EnvFree = EnvSize - SeekEOS() - 2 return end if i = i + length(str) + 1 end while end procedure -- EraseVar() procedure SetVar(sequence name, sequence value) -- set the value of an environment variable -- input: name is variable name -- value is value affected to variable integer i if length(name) + length(value) + 1 > EnvFree then return -- not enough space end if if length(GetVar(name)) > 0 then EraseVar(name) -- erase old value end if i = SeekEOS() poke(EnvAddr+i,name&'='&value&0&0) end procedure -- SetVar() ------------------------------------------------------------------------------ sequence FileName integer dotpos EnvAddr = GetParentEnv() -- get environment size from dos memory control block. EnvSize = 16*(peek(EnvAddr-13)+peek(EnvAddr-12)*256) EnvFree = EnvSize - SeekEOS() - 2 FileName = GetVar("FILE") if length(FileName) = 0 then puts(1,"Environment variable FILE not found.\n") abort(1) end if dotpos= find('.',FileName) if not dotpos then SetVar("NAME",FileName) SetVar("EXT","") else SetVar("NAME",FileName[1..dotpos-1]) SetVar("EXT",FileName[dotpos+1..length(FileName)]) end if --=====================_849413188==_ @echo off echo. echo current environment set set FILE=%1 ex envdemo echo. echo name is %NAME% echo extension is %EXT% set FILE= set NAME= set EXT= --=====================_849413188==_ Jacques Deschenes Baie-Comeau, Quebec Canada desja at quebectel.com --=====================_849413188==_--