ossp-pkg/rc/00TODO
1.16
00TODO: Tasks left to accomplish before rc is complete
Unfinished business
Manpage options incorrectly specifies multiple rc.funcs.
What when multiple command interpreters and one --print or --eval given?
File rc.func totally undocumented, but logic should be clear.
Control flow
Explain logical ordering of multiple section spanning multiple rcfiles.
Give example semantics of a common scenario.
No error semantics in pseudocode.
Consider
Removing the OSSP_RC_DEACT deactivation feature (thl.)
Make return code and error definitions unique to OSSP rc.
Offer include directive in config file.
Dynamic handling of command interpreter option.
Environment of manpage has redundant text.
Interpreter option irgendwo dass hat global scope.
Als variable in %config Section?
Must do
Strip local getopt and popt code, and use OSSP popt library.
Translate rc bourne shell script to ANSI C.
Finish man page. Start latex or Docbook guide.
If a variable is defined for which no default exists, warn user (Scholli.)
Document
Refs, pri, user, group, ci, go only in normal (not special) sections.
Detailed ;-) project plan
-------------------------
Release v0.8
Milestone 1, Drop in replacement for OpenPKG.
Release v0.9
Milestone 2, Additional features in build.
Release v1.0
Milestone 3, Cleanup and bugfix.
Release v1.2
Milestone 4, Krasse L2 Logging und eigene Sprache
Dreams
Log to an L2 channel
Channel specification could go in rc.conf
Processing language
!if !else (conditional processing can cross-reference local config vars)
!print <var> (print something to stdout)
!logit <var> (log something, mstone1-3 to syslog, mstone4 to L2)
!lineno [LAST] (the current line number or last successful command)
!rcfile [EXISTS|ABSOLUTE] (info about an rcfile)
# Is there a way to merge rcfile and rc processor contexts?
!envarpush <string> (push an environment variable on the rc stack)
!envarpop (pop an environment variable from the rc stack)
!throw [var] (returns var to rc processor and ask rc to return -1)
!exit [var] (returns var to the rc processor and asks rc to abort execution)
!return <var> (signals end of section and returns var to rc processor)
...
/-------------------OSSP rc Inhalt------------------\
| Manpage |
| rc.1 Section 1 oder 8-Konflict? |
| rc-sample.5 Vielleicht umnennen rc.samples.5 |
| rc.conf.5 Beschreibung aber kein Beispiel |
| |
| Geliefert |
| rc.env Leer |
| rc.conf Ausgekommentet Beispiel |
| |
| Beispiele |
| rc.example Soll rc.foo umgenannt werden |
\---------------------------------------------------/
Pseudocode
***********************************
* psoudocode implementation of rc *
***********************************
parse command line
merge all 'rc.conf' files
read environment variables
build option table
parse 'Locate'
Locate /cw/etc/rc.d/rc.%{RCFILE:s/^all$/*/}
Locate /cw/local/etc/rc.d/rc.%{RCFILE:s/^all$/*/}
Locate %{RCFILE}/.duerc
Locate ${HOME}/.duerc:m/^<dir path="%{RCFILE}">(.*)<\/dir>/i
Locate ${HOME}/.duerc.%{RCFILE:s/^\///:s/[\/]/-/g}
Locate path/file/regex:regex_inside_file
for each 'Locate' {
for each (all rcfiles after variable expansion and shell globbing) {
apply path conversion to rcfilename
continue if (absolute path seen previously) // avoid duplicates
if (filename matches given rcfile)
if (securitycheck(RequireUmask, RequireOwner, RequireGroup))
read and strip file ('Locate' regex, after colon)
}
}
for each rcfile_fraction {
parse into blocks according to --ParseSectionDef
take out %config section according to --NameConfig
take out %common section according to --NameCommon
take out %error section according to --NameError
take out %default section according to --NameDefault
app.mapSections; // create the section map
}
mapSections () // Map nonexisting %sections to %default
{ // from now on, 'section' implies 'section->lookupMapval'
while (tempSection := ParsedCLI->nextSection) // CLI = command line iface
if (rcfile_fraction->has(tempSection))
rcfile_fraction->sectionNames += tempSection;
else if (rcfile_fraction->has(%default))
rcfile_fraction->sectionNames += %default;
else handle error
}
for each section on command line {
if (multiple rcfiles, i.e. all)
sort rcfiles by section priority (%defaults are last)
for each rcfile {
script = "";
script += %config from rcfile
script += rc.env (overriding any duplicate values)
create_rcfile_script(script, section, recurse=no)
expand internal variables
execute, print, or printeval script with user & group priveleges
and command interpreter according to options or section header
}
}
EXIT
create_rcfile_script(script, section, recurse)
{
script += "${body}" // start with a pseudo value
if (!recurse) { // only one rc.func is possible
if no ${body} in rc.func->%common prepend ${body} to rc.func->%common
replace script->${body} with rc.func->%common
}
if no ${body} in rcfile->%common prepend ${body} to rcfile->%common
replace script->${body} with rcfile->%common
if (!recurse) { // only one rc.func is possible
if no ${body} in rc.func->%section prepend ${body} to rc.func->%section
replace script->${body} with rc.func->%section
}
replace script->${body} with rcfile->%section
while (ref := ParseSectionRef(script))
ref->create_rcfile_script(recurse=yes);
}