cproc

CPROC - Interactive Terminal Command Processor ../sdsys/GPL.BP/CPROC

Many of the system commands (also known as Verbs) are nothing more than basic programs (however there are “internal” commands handled directly by CPROC, see list below).

These commands can be:

Commands can be entered from a “terminal” and have an associated “VOC” file entry: VOC type “V” for Verb or locally catalogued subroutine.

Field2

Field3

Description

CA

name

Catalogued verb

CS

path

Locally catalogued function runfile path

IN

n

Internal verb number n (see below for list of Internal Verbs)

OS

text

Operating system command

Field4 = dispatch info (@option) for all verbs

Field5 = security subroutine (optional)

Commands processed as part of a Paragraph (VOC type “PA” which in turn is made up of a list of commands)

User Name:

Setting up the user name.
The user name is stored in 3 different places: USER_ENTRY table. structure PROCESS at both process.username and in the syscom common block (process.syscom).
The linux user name is picked up in vm code kernal.c function init_kernel().
The init_kernel() function uses (!GetUserName((char*)(my_uptr->username), &m)) to place the user name in the USER_ENTRY table,
then uses strcpy(process.username, (char*)(my_uptr->username)) to place in structure PROCESS at process.username.
Finally CPROC has the line logname = kernel(K$USERNAME, 0) which places user name in syscom common (at postion 14).
(kernel(K$USERNAME, 0) returns the user name found in process.username, see op_kernel in op_kernel.c)

The @logname (and @user) @ functions retrieve the user name from syscom logname (the 14 entry in process.syscom) see op_ldsys() in op_loads.c

Special note about running with root privileges (sudo sd):

All administrative tasks within SD must be performed from account SDSYS.
In order to log into account SDSYS, SD must be started with root privileges  (sudo sd).
Since running with root privileges allows the process to perform system wide tasks,
it is recommended to only run at this level when necessary.  When SD is run as root,
the command processor (CPROC) will drop the effective user id (euid) of the process to that of user SDYS.

Administrative commands that require root privileges are defined with in the CPROC code in dynamic array
privileged_commands.
  privileged_commands = ''
  privileged_commands<-1> = "$CREATEA"  ;*"CREATE.ACCOUNT"
  privileged_commands<-1> = "$DELACC"   ;*"DELETE.ACCOUNT"
  privileged_commands<-1> = "$MODIFYA"  ;*"MODIFY.ACCOUNT"

When commands defined in privileged_commands are executed, the euid of the process is restore to that of root,
the command is executed, and the euid is dropped back down to that of SDYS.

pseudocode:

If this is the first time through CPROC (kernel(K$CPROC.LEVEL,0) ==0):
   initialize various things in the SYSCOM common block
   execute $LOGIN program
       If this is a telnet or serial connection prompt for user name and password, validate with op_login (kernel.c) which calls
       login_user(un,pw) found in linuxio.c
   if not valid login abort.cproc
   if logging in root (sudo sd) call EUID_SET to drop euid /egid to that of sdsys
   If phantom session:
       setup COMO file record for this session
       set phantom command options
   endif
   Execute MASTER.LOGIN paragraph
   Execute LOGIN paragraph

else * Stacked CPROC, abort or LOGTO RESET
   get.voc.parser.rec (ln428)
   Inc CPROC stack depth ( kernel(K$CPROC.LEVEL,kernel(K$CPROC.LEVEL,0)+1) )
endif (ln520)

if EXECUTE command (flag setting in Object Header defined in header.h both basic and c versions) Not exactly sure how that gets set - needs investigating
   xeq.command is command name (stored in $syscom common block not sure how it gets there!, look at kernel((K$CPROC.LEVEL,..) see what it does

   executed via creating "local" voc record: voc.rec = 'PA':@fm:xeq.command)
   calls execute.paragraph which ends up calling proc.para.sentence and eventually end up at execute.commad: (ln1406)
   goto abort.cproc (ln557) see below


if is phantom process (ln562)
    Execute the phantom command
    gosub proc.sentence
    goto abort.cproc
 else
   this is a single command invocation of SD (user typed sd "LIST VOC" on os command line window).
       gosub proc.sentence
       goto abort.cproc
end


**
* Main command processor loop
**
 connected.port:

Loop
   gosub reset.environment
   gosub set.links             ;* Unsnap subroutine links
   unload.object               ;* Unload inactive object code
   debug.off                   ;* Ensure debugger turned off
   debug.initialised = @false  ;* Force restart of debugger

   * Fetch new command
   loop
       gosub get.command.line which returns at.command
       until at.command # ""
       repeat
       new.sentence = at.command
       gosub proc.sentence

repeat  - loop repeats until some sort of abort or exit


proc.para.sentence:
proc.sentence:
proc.command:           note: these are all entry points that eventually end up at execute.command

   parse sentence and look for VOC record for command

execute.commad:

CASE VOC is TYPE:

   User Defined VOC type
       Process Command (CALL @handler) with handler defined in $VOC.PARSER record

   VERB    voc.entry.type[1,1] = "V"

   Verbs
       Type "CA" - call catalogued command stored in Field3 via @call
           For privileged_commands perform EUID_RESTORE  @call followed by EUID_SET
       Type "CS" - call Locally catalogued function via @call
       Type "IN" - internal CPROC command (see internal verbs list below)
       Type "OS" - OS command - gosub os.command
       Type "EX" - Executable - gosub run.exe  <-- need to look more into these two

   PROC voc.entry.type[1,2] = 'PQ' - old PROC PROCESSOR for R83  compatibility

   REMOTE voc.entry.type[1,1] = 'R'

   SENTENCE voc.entry.type[1,1] = "S"

   PARAGRAPH voc.entry.type[1,2] = "PA"

   MENU voc.entry.type[1,1] = "M"

   KEYWORD voc.entry.type[1,1] = "K"

   PRIVATE CATALOG ENTRY (BASIC PROGRAM  which is executed via creating local voc record: voc.rec = 'V':@fm:'CA':@fm:verb) and jumping back up to execute.commad (ln1406)

   GLOBAL CATALOG ENTRY  (BASIC PROGRAM  which is executed via creating local voc record: voc.rec = 'V':@fm:'CA':@fm:verb) and jumping back up to execute.commad (ln1406)

CASE 1 - Error Message - not in VOC

exit.command:
   If CPROC entry
       Dec CPROC level
        i = kernel(K$CPROC.LEVEL,0)
        delete.common '$':i   ;* Delete unnamed common
        i = kernel(K$CPROC.LEVEL, i - 1)
Return



abort.cproc:
   dec command level with code:
       i = kernel(K$CPROC.LEVEL,0) - 1
       void kernel(K$CPROC.LEVEL,i)     ;* Decrement command level

terminate.cproc:   return to terminate.cproc
   From Documentation:
       Sometimes a subroutine needs to return to the calling routine but it is not known how many internal subroutines may be active.

           ERROR.LABEL: RETURN TO ERROR.LABEL

       This will cause all internal subroutines to return to the RETURN statement and then return to the calling program



Internal Commands:

Verb type = "IN"  ;* Internal CPROC command processed by corresponding CPROC internal subroutines:

     on voc.rec<3> gosub int.quit,  ;*  1  Quit (or OFF, see VOC entry for OFF)
        int.clr,                    ;*  2  Clear screen
        int.display,                ;*  3  Display text at terminal
        int.run,                    ;*  4  Run program
        int.abort,                  ;*  5  ABORT
        int.clearselect,            ;*  6  Clear select list
        int.date,                   ;*  7  DATE
        int.time,                   ;*  8  TIME
        int.break,                  ;*  9  BREAK
        int.bell,                   ;* 10  BELL
        int.go,                     ;* 11  GO
        int.status,                 ;* 12  STATUS
        int.set.date,               ;* 13  SET.DATE
        int.help,                   ;* 14  HELP
        int.update.account,         ;* 15  UPDATE.ACCOUNT
        int.who,                    ;* 16  WHO
        int.logto,                  ;* 17  LOGTO
        int.if,                     ;* 18  IF
        int.cleardata,              ;* 19  CLEARDATA
        int.clearprompts,           ;* 20  CLEARPROMPTS
        int.clear.stack,            ;* 21  CLEAR.STACK
        int.echo,                   ;* 22  ECHO
        int.hush,                   ;* 23  HUSH
        int.sleep,                  ;* 24  SLEEP
        int.clearinput,             ;* 25  CLEARINPUT
        int.clear.locks,            ;* 26  CLEAR.LOCKS
        int.lock,                   ;* 27  LOCK
        int.logout,                 ;* 28  LOGOUT
        int.debug,                  ;* 29  DEBUG
        int.stop,                   ;* 30  STOP
        int.report.src,             ;* 31  REPORT.SRC
        int.pterm,                  ;* 32  PTERM
        int.date.format,            ;* 33  DATE.FORMAT
        int.set,                    ;* 34  SET
        int.umask,                  ;* 35  UMASK
        int.pdump,                  ;* 36  PDUMP
        int.pause,                  ;* 37  PAUSE
        int.clear.abort,            ;* 38  CLEAR.ABORT
        int.set.exit.status,        ;* 39  SET.EXIT.STATUS
        int.report.style,           ;* 40  REPORT.STYLE
        int.logmsg                  ;* 41  LOGMSG

End of CPROC description