[Woody - dboostrap] RFC: Common shell script to implement file parsing?
I think that we could generalize the "/proc/*" (and other) file
parsing; fold it all together into one function that calls a shell
script inside a `popen()', and that shell script can do the file
parse and print out the parts needed in an easy to grab from C
format, like one item per line for `readline()' consumption, or
delimitted for `sscanf()'ing it, maybe. Hmmm. One line at a time
for an iteration that wants one value at a time... sscanf parseable
for when we want a multi-value return? Hmmm.2 or pass an arg to the
generalized file iterator telling it how many lines to return?
... and return them in a passed **argz (search glibc manual for
"argz") or what?
I think it would reduce the size of `dbootstrap' a little bit,
perhaps leaving a little room for UI code growth. It would get rid
of several special purpose file parser routines and combine them into
one. We have a high level language available - POSIX `sh'. Why not
utilize it for what it's designed for, instead of writing C code that
reinvents the `sh' `read' builtin? There are probably other things
we could do from a subshell like that.
All of the necessary functions for the `popen()' are, of course,
already part of our .so subset, courtesy of `ash', which uses lots of
stuff we do not...[1] Using this approach will therefore not increase
the size of our library subset. It probably won't reduce it, but
will hopefully melt a little of the fat out of `dbootstrap' itself.
If that shell script grows large enough, it can be compressed with
`gzip' and run via `zcat | sh', passing arguments to it via the
environment. Even better, Erik's mini shell, in BusyBox, could
probably be given support for executing `gzip' encoded scripts.
(hmmm.) I guess it would just need to do whatever `file' does --
look for the magic at the start of the file -- and if it finds a gzip
encoded script, then zcat it's script input stream.
For most files we parse stuff out of, I think that the sh `read' and
`echo' builtins (perhaps in combination with appropriate IFS
settings) will do everything we need, and there's always `sed' if
it's a really hairy parse.
What are all the files we open and parse that could be read this way?
/proc/sys/dev/cdrom/info <-- choose_cdrom()
/proc/filesystems <-- nope - just grep it.
/proc/net/dev <-- util.c:getif_*()
Reading the Linux boot command line can be done prior to launching
`dbootstrap', if we start it via a shell script wrapper that does the
file parse, sets up the environment, then calls `exec dbootstrap'.
Other things could be set up then also, such as sourceing a
`dbootstrap' meta-data "environment" file, the elements of which will
then be available to `getenv()' inside `dbootstrap' itself. Q: What
happens if I `getenv()', then mutate or replace that return value,
then call `setenv()'? Can I iterate over the **environ array and see
each of them, like from within an exit (segv, hup, exit, ...) trap
function that writes that back out to disk? Crash proof by writing
to a .new then rm and rename? (how does `dpkg' handle that?)
This meta-data "environment" would then be used as the canonical set
of values for presentation by the UI, and as the database of values
where what gets written to actual configurations for various daemons
is stored by `dbootstrap', rather than in global variables. The
entire set, an augmented set, a subset, or an augmented subset of
that environment can be passed as the **env to our `popen()'ed file
parser shell script.
Footnotes:
[1] I think that the library reducer ought to be rewritten, in Guile,
to speed it up and make it beautiful. I'd like to try and take
this on. I really want to be learning Scheme right now, rather
than working on `boot-floppies'... If I spend time on a library
reducer, I can do both at once.
Reply to: