(!******************************************************
Mosel Example Problems
======================
file bpack.mos
``````````````
Encapsulate any kind of binary file into a .bim file.
The binary gets extracted when running the resulting .bim file.
- Using the 'datablock' functionality -
Compilation into an executable (requires a C compiler):
mosel comp bpack.mos -o deploy.exe:bpack
Usage:
bpack mybinaryfile.ext
(results in a file mybinaryfile_ext.bim)
mosel run mybinaryfile_ext.bim
(to extract the original binary file from the .bim)
Usage without generation of an executable:
mosel bpack.mos F=mybinaryfile.ext
(c) 2019 Fair Isaac Corporation
author: Y. Colombani, 25 Apr 2019
*******************************************************!)
model bpack
version 0.1.0
uses 'mmsystem','deploy','mmjobs'
parameters
F="" !@doc.descr Name of binary file to be encapsulated
end-parameters
public declarations
!@doc.descr Source of the model file used for the generation of a .bim that contains the specified binary file
SRC=`
model bextract
uses 'mmsystem'
include "mem:srcfile"
write("Extract '",F,"' ?[Y/n] ");fflush
a:="Y"
readln(a)
if a.size>=1 and (getchar(a,1)=89 or getchar(a,1)=121) then
if getfstat(F)<>0 then
write("File already exists: overwrite it?[y/N] ");fflush
a:="N"
readln(a)
if a.size<1 or (getchar(a,1)<>89 and getchar(a,1)<>121) then
writeln("Operation aborted.")
exit(1)
end-if
else
fcopy(datablock(FSRC),F_BINARY,F,F_BINARY)
exit(getsysstat)
end-if
else
writeln("Operation aborted.")
exit(0)
end-if
end-model
`
end-declarations
declarations
! Internal subroutines
procedure banner ! Display a banner
procedure showhelp ! Display help text
function basename(f:text):text ! Aux. routine returning basename
function build_kls:text ! Build KLS parameter
procedure readkeys(f:string) ! Read public keys from a file
fname:text ! Name of binary file to encapsulate
flags:text ! Compilation flags
kls:list of text ! List of public keys
pke:text ! Private key (for signing)
pass:text ! Encryption password
silent:boolean ! Whether to report activity
force:boolean ! Whether to overwrite existing files
end-declarations
! Handling of run mode (Mosel model or executable) and runtime parameters
if argc=1 and argv(1)="mosel" then ! Not deployed: use parameter
fname:=F
elif argc=1 then
banner
showhelp
exit(0)
else
a:=2
repeat
if argv(a)="-V" then
banner
exit(0)
elif argv(a)="-s" then
silent:=true
elif argv(a)="-f" then
force:=true
elif argv(a)="-S" then
flags+="-S"
elif argv(a)="-E" then
flags+="-E"
elif argv(a)="-T" then
flags+="-T"
elif argv(a)="-k" then
if a<argc then
a+=1
kls+=[text(argv(a))]
end-if
elif argv(a)="-kf" then
if a<argc then
a+=1
readkeys(argv(a))
end-if
elif argv(a)="-pwd" then
if a<argc then
a+=1
pass:=argv(a)
end-if
elif argv(a)="-pk" then
if a<argc then
a+=1
pke:=argv(a)
end-if
else
break
end-if
a+=1
until a>argc
if a<>argc or getchar(argv(a),1)=45 then
banner
showhelp
exit(1)
else
fname:=argv(a)
end-if
end-if
! Remove leading or trailing blanks from input filename
trim(fname)
if fname.size=0 or bittest(getfstat(fname),SYS_TYP)<>SYS_REG then
if not silent then
writeln("File '",fname,"' not found or invalid")
end-if
exit(1)
else
if getfsize(fname)=0 and not silent then
writeln("Warning: file '",fname,"' is empty")
end-if
dst:=pathsplit(SYS_FNAME,fname)
! Write binary file contents into an 'include' file for the generated model
fopen("mem:srcfile",F_OUTPUT)
writeln("declarations\nFSRC='",fname,"'\nF='",dst,"'\nend-declarations\n")
fclose(F_OUTPUT)
! Create the Mosel model file name from the original filename
asproc(regreplace(dst,'\.','_'))
dst+=".bim"
! Check whether it is acceptable to overwrite an existing file
if getfstat(dst)<>0 and not force then
if silent then
exit(2)
else
write("File '",dst,"' already exists.: overwrite it?[y/N] ");fflush
ans:="N"
readln(ans)
if ans.size<1 or (getchar(ans,1)<>89 and getchar(ans,1)<>121) then
writeln("Operation aborted.")
exit(1)
end-if
end-if
end-if
! Compile the resulting generated model
if compile(flags,"text:SRC",dst,"Produced by BPACK "+getparam("model_version"),pass,pke,build_kls)<>0 then
if not silent then
writeln("Compilation failed. Aborting")
end-if
exit(1)
elif not silent then
writeln("File recorded in '",dst,"'. Execute the following to restore it:")
writeln(" mosel run ",dst)
if findtext(flags,"S",1)>0 then
if pke.size>0 then
writeln("The file is signed with the private key '",pke,"'.")
else
writeln("The file is signed with your personal private key.")
end-if
end-if
if findtext(flags,"E",1)>0 then
if pass.size>0 then
writeln("The file is encrypted using password '",pass,"'.")
elif kls.size>0 then
writeln("The file is encrypted using the following public keys: ",kls,".")
else
writeln("The file is encrypted using your personal public key.")
end-if
end-if
end-if
end-if
!***********************
!* Display Banner
!***********************
procedure banner
writeln("FICO Xpress ",basename(argv(1))," v",getparam("model_version"))
writeln("(c) Copyright Fair Isaac Corporation 2019. All rights reserved")
writeln(_("Link date"),": ",getparam("parser_date")," ",getparam("parser_time"))
end-procedure
!***********************
!* Display some help
!***********************
procedure showhelp
writeln_("\nUsage: ",argv(1)," -V|[-s] [-f] [-S] [-E] [-k key] [-kf kfile] [-pwd pass] filename\n")
write_(`
-V: display banner and exit
-s: silent mode
-f: overwrite existing file
-S: sign the generated bim file
-E: encrypt the generated bim file
-k key: add public key 'k' for encryption
-kf kfile: add public keys from file 'kfile' for encryption
-pwd pass: use 'pass' for encryption
-pk priv: use 'priv' key for signing
By default a bim file including the provided file is created.
The provided file can be extracted by running the resulting bim file.
`)
end-procedure
!**********************************************************************
!* Extract the basename of a path (i.e. strip directory and extension)
!**********************************************************************
function basename(f:text):text
returned:=pathsplit(SYS_FNAME,f)
asproc(pathsplit(SYS_EXTN,returned,returned))
end-function
!********************************************
!* Produce the kls file from a list of texts
!********************************************
function build_kls:text
if kls.size>0 then
returned:="mem:pkeys"
fopen(returned,F_APPEND)
forall(k in kls)
writeln(k)
fclose(F_OUTPUT)
end-if
end-function
!******************************
!* Get public keys from a file
!******************************
procedure readkeys(f:string)
declarations
l:text
end-declarations
fopen(f,F_INPUT)
while(readtextline(l)>0) do
trim(l)
if l.size>0 and getchar(l,1)<>35 then
kls+=[text(l)]
end-if
end-do
fclose(F_INPUT)
end-procedure
end-model
|