Initializing help system before first use

Encapsulate binary file into a BIM


Type: Programming
Rating: 3 (intermediate)
Description: The 'bpack' tool encapsulates a user-specified binary file into a BIM file using the 'datablock' functionality. The binary file gets extracted into the working directory when running the resulting BIM file.
The model can be deployed as an executable (requires a C compiler):
mosel comp bpack.mos -o deploy.exe:bpack
bpack name_of_file_to_include
or run as a standard Mosel model, e.g. from the command line:
mosel bpack.mos F=name_of_file_to_include
The name of the binary file to be included needs to be specified via a runtime parameter. A file myfile.extension will result in the creation of a BIM file named myfile_extension.bim from which the original binary file is extracted when running the BIM, e.g via the command
mosel run myfile_extension.bim
File(s): bpack.mos


bpack.mos
(!******************************************************
   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

© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.