diff --git a/software/cinit/archives.html b/software/cinit/archives.html
new file mode 100644
index 00000000..40e830f1
--- /dev/null
+++ b/software/cinit/archives.html
@@ -0,0 +1,276 @@
+
+
+
+unix.schottelius.org
+
+
+
+Nico Schottelius
+
unix.schottelius.org
+
cinit
+
+
+
+
+You can view the latest source in
+gitweb
+or clone it with git.
+
+
+ - cinit-0.3pre14.tar.bz2
+ (browse source)
+ (latest development)
+
+ - Added test-suite for cmd
+
- Added support to shutdown services in cinit and cmd (without needs and wants)
+
- Added linux-sysvinit wrapper for shutdown (See scripts/wrapper/linux-sysvinit/shutdown)
+
- Rewrote most parts of cmd (to make it more beautiful)
+
- Changed license to GPL 3
+
- WARNING: This is next-to- production release. Thought
+ to be used for testing.
+
+
+ - cinit-0.2.1.tar.bz2
+ (browse source)
+ (latest stable)
+
+ - Fixed problem in contrib+tools/Makefile when installing
+
- added many new scripts to convert sys-v-init, which are still early beta
+ (see
+ bin/cinit.merge.sysvinit-debian-sid
+
+
+
+
+
+ - cinit-0.3pre13.tar.bz2
+ (browse source)
+ (latest development)
+
+ - Added -V (get cmd version), -h (help), -p (get pid) to cmd
+
- Cleaned up namemsage in msgq.h
+
- Added global service lock
+
- Splitted of svc.h to svc.h, svc-intern.h and svc-messages.h
+
- Prepared logic splitoff from cinit_ipc_listen()
+
- Fixed bug: fork() has a general race condition (see src/test/fork-latency.c) through use of global lock
+
- WARNING: This is next-to- production release. Thought
+ to be used for testing.
+
+ - cinit-0.3pre12.tar.bz2
+ (browse source)
+ (latest development)
+
+ - Added DESTDIR support
+
- Added support to get service status via cmd: cmd -s
+
- also supports relative paths to CINIT_DIR ("/etc/cinit")
+ - Fixed git clone problem: hooks are needed for dumb git
+
- Fixed bug: We did not wait for services to finsh, which we
+ depend on being ran once.
+
- WARNING: This is pre- production release. Thought
+ to be used for testing.
+
+ - cinit-0.3pre11.tar.bz2
+ (browse source)
+ (latest development)
+
+ - Added basic communication: client binary "cmd" with argument -v returns cinit-version
+
- Updated {halt,reboot,poweroff}.kill
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+ - cinit-0.3pre10.tar.bz2
+ (browse source)
+ (latest development)
+
+ - Fixed make install target
+
- Added halt.kill, poweroff.kill and reboot.kill (including manpages!)
+
- Fixed invalid comparision in core/cinit.c
+
- Be verbose: Print what we execute
+
- Updated documentation
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre9.tar.bz2
+ (browse source)
+ (latest development)
+
+ - Implemented sleeping before respawn (static delay)
+
- Report broken links on execution, but ignore empty services
+
- Cleaned up message queue error reporting
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre8.tar.bz2
+ (browse source)
+
+ - Updated and merged documentation: Codingstyle and Codingguide
+
- Cleaned sigaction-code (fixes segfault on glibc)
+
- Cleaned object listings
+
- Added notifications at shutdown
+
- Fixed status check
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+ - cinit-0.3pre7.tar.bz2
+ (browse source)
+
+ - Many code cleanups
+
- Fixed glibc problem with sigaction (for details view src/core/set_signals.c)
+
- Added general shutdown support (will *NOT* yet stop services, but still stop your system)
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre6.tar.bz2
+ (browse source)
+
+ - Many code cleanups
+
- Added user documentation and cleaned up documentation in general
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre5.tar.bz2
+ (browse source)
+
+ - Finished new SIGCHLD handler
+
- First cleanups for real release.
+
- This version is the first 0.3pre version that can handle respawn!
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre4.tar.bz2
+ (browse source)
+
+ - Re-implemented execution of services
+
- This version is the first 0.3pre version that COULD bootup your system!
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre3.tar.bz2
+ (browse source)
+
+ - Finished execution all services via the reversed service tree.
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.3pre2.tar.bz2
+ (browse source)
+
+ - Finished generation of dependency tree.
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+ - cinit-0.3pre1.tar.bz2
+ (browse source)
+
+ - Developer test release - please compile on different archs, different
+ Unices. This should be the first portable version.
+
- WARNING: This is NOT a production release. Only thought
+ to be used for testing.
+
+
+ - cinit-0.2.tar.bz2
+ (browse source)
+
+ - Much more verbose error reporting
+
- You can now also disable 'once ran' services,
+
- You can restart services with cservice -r
+
- C_DELAY support - variable delay for sending SIGKILL after SIGTERM
+
- Added tools to analyze cinit configuration
+ (cinit-vis.pl, cinit.graph.text.c)
+
- Added tools to import and export configuration to XML
+ (make.cconfig.from.xml.rb,cconfig.graph.xml.rb)
+
- Removed unecessary signalling
+
- Added many helper scripts to install services (cinit.install.service*)
+
- Fixed many small bugs in old helper scripts
+ (cinit.add.getty, cinit.get-conf, ...)
+
- Added ccontrol, which allows to control cinit
+
- Added update (-u) via ccontrol
+
- Stripped cservice, which now "only" controls services
+
- Removed swapoff from cinit code, should be handled by off
+
- Much better error and processing descriptions
+
- A bit more verbose reporting
+
- Restructured run_svc, now with better error detection
+
- Removed Kernel panic, when halting system
+
+ - cinit-0.1.tar.bz2
+ (browse source)
+
+ - Added cservice -u: Hot-Reboot (restart everything without
+ a real reboot) and update cinit without rebooting
+
- The shell scripts cinit.reboot and cinit.shutdown
+ are also installed now.
+
- Changed profile parameter to "cprofile:", as "cprofile="
+ is eaten by the kernel
+
- cservice -a accepts now relative paths as -e does
+
- cservice is now a bit more verbose about what it does
+
- cinit now reports, if a service failed
+
- Removed O_ASYNC / SIGIO (signalling has race conditions)
+
- Fixed small bug in cinit.create.empty.service and cinit.read-conf
+
- Fixed Makefile to allow parallel building (thanks to Mike Frysinger)
+
- Fixed install bug, which did not create /sbin (thanks to Mike Frysinger)
+
- Updated much documentation
+
+ - cinit-0.0.8.tar.bz2
+ (browse source)
+
+ - Support for
+ variable delay
+ (file: delay)
+
- Support for
+ Rescue mode
+ (only a shell, everything turned of; see doc/using.rescue)
+
- Added cservice: control your cinit
+
- Support for killing services
+
- Support for starting services
+
- Support for zombies (we clean them up now,
+ see doc/removing.zombies)
+
- Added test-script for UML (User-Mode-Linux): bin/cinit.uml.test
+
- Added documentation about replacing your init
+ (doc/replacing.init)
+
- Added some security notes (doc/security)
+
- Fixed cpu-consuming bug
+
- Fixed killing service watchers (they kill their children themself now)
+
+ - cinit-0.0.7.tar.bz2
+ (browse source)
+ - "Need" dependencies had a small bug, where one service would not wait
+ for the needed service if some other process is already working on it.
+ Fixed another bug, umount had wrong arguments (three times the first argument,
+ typo in source). Added missing call to sync() before umount.
+ Fixed bug in profile code (cinit accepted cprofile=profile, but didn't care
+ about it). Updated the shipped tarball to support openssh, fsck for root device
+ (others can be added easily). Added cinit.reboot to reboot system
+ (in bin/). Added more documentation.
+
- cinit-0.0.6.tar.bz2
+ (browse source)
+ - much more documenatation,
+ new profile support!
+
- cinit-0.0.5.tar.bz2
+ (browse source)
+ - much new documenatation, stricter checking and fixing Makefile issues
+
- cinit-0.0.4.tar.bz2
+ (browse source)
+ - first official release
+
+
+
+Warning: It looks like the Debian packages are not up-to-date
+currently. Please use the source instead.
+
Marcus Wagner makes cinit available as Debian packages.
+
To get cinit insert the following line into your /etc/apt/sources.list:
+
+deb http://deb.notestc.de/ clinux/
+
+Than do
+apt-get update && apt-get install cinit
+
+
+
+
diff --git a/software/cinit/archives/cinit-0.0.4.tar.bz2 b/software/cinit/archives/cinit-0.0.4.tar.bz2
new file mode 100644
index 00000000..bfbb2ffe
Binary files /dev/null and b/software/cinit/archives/cinit-0.0.4.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.0.5.tar.bz2 b/software/cinit/archives/cinit-0.0.5.tar.bz2
new file mode 100644
index 00000000..3c17cf53
Binary files /dev/null and b/software/cinit/archives/cinit-0.0.5.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.0.6.tar.bz2 b/software/cinit/archives/cinit-0.0.6.tar.bz2
new file mode 100644
index 00000000..b94d60b3
Binary files /dev/null and b/software/cinit/archives/cinit-0.0.6.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.0.7.tar.bz2 b/software/cinit/archives/cinit-0.0.7.tar.bz2
new file mode 100644
index 00000000..6fc175ec
Binary files /dev/null and b/software/cinit/archives/cinit-0.0.7.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.0.8.tar.bz2 b/software/cinit/archives/cinit-0.0.8.tar.bz2
new file mode 100644
index 00000000..3ec8a8be
Binary files /dev/null and b/software/cinit/archives/cinit-0.0.8.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.1.tar.bz2 b/software/cinit/archives/cinit-0.1.tar.bz2
new file mode 100644
index 00000000..7f5ea6a0
Binary files /dev/null and b/software/cinit/archives/cinit-0.1.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.2.1.tar.bz2 b/software/cinit/archives/cinit-0.2.1.tar.bz2
new file mode 100644
index 00000000..e2ee3f0a
Binary files /dev/null and b/software/cinit/archives/cinit-0.2.1.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.2.tar.bz2 b/software/cinit/archives/cinit-0.2.tar.bz2
new file mode 100644
index 00000000..128ec24c
Binary files /dev/null and b/software/cinit/archives/cinit-0.2.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre1.tar.bz2 b/software/cinit/archives/cinit-0.3pre1.tar.bz2
new file mode 100644
index 00000000..b643c8f2
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre1.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre10.tar.bz2 b/software/cinit/archives/cinit-0.3pre10.tar.bz2
new file mode 100644
index 00000000..6147c67a
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre10.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre11.tar.bz2 b/software/cinit/archives/cinit-0.3pre11.tar.bz2
new file mode 100644
index 00000000..c71d80b7
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre11.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre12.tar.bz2 b/software/cinit/archives/cinit-0.3pre12.tar.bz2
new file mode 100644
index 00000000..0b1b1221
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre12.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre13.tar.bz2 b/software/cinit/archives/cinit-0.3pre13.tar.bz2
new file mode 100644
index 00000000..680fa9c6
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre13.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre14.tar.bz2 b/software/cinit/archives/cinit-0.3pre14.tar.bz2
new file mode 100644
index 00000000..34293ea7
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre14.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre2.tar.bz2 b/software/cinit/archives/cinit-0.3pre2.tar.bz2
new file mode 100644
index 00000000..4dacbb25
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre2.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre3.tar.bz2 b/software/cinit/archives/cinit-0.3pre3.tar.bz2
new file mode 100644
index 00000000..016ed57d
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre3.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre4.tar.bz2 b/software/cinit/archives/cinit-0.3pre4.tar.bz2
new file mode 100644
index 00000000..83309598
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre4.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre5.tar.bz2 b/software/cinit/archives/cinit-0.3pre5.tar.bz2
new file mode 100644
index 00000000..86480d7e
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre5.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre6.tar.bz2 b/software/cinit/archives/cinit-0.3pre6.tar.bz2
new file mode 100644
index 00000000..fdcb5ae1
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre6.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre7.tar.bz2 b/software/cinit/archives/cinit-0.3pre7.tar.bz2
new file mode 100644
index 00000000..873d47d9
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre7.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre8.tar.bz2 b/software/cinit/archives/cinit-0.3pre8.tar.bz2
new file mode 100644
index 00000000..1de2bdf9
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre8.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-0.3pre9.tar.bz2 b/software/cinit/archives/cinit-0.3pre9.tar.bz2
new file mode 100644
index 00000000..d98a0a90
Binary files /dev/null and b/software/cinit/archives/cinit-0.3pre9.tar.bz2 differ
diff --git a/software/cinit/archives/cinit-snapshot.tar.bz2 b/software/cinit/archives/cinit-snapshot.tar.bz2
new file mode 100644
index 00000000..5b4b97eb
Binary files /dev/null and b/software/cinit/archives/cinit-snapshot.tar.bz2 differ
diff --git a/software/cinit/browse_source/cinit-0.0.4/BUGS b/software/cinit/browse_source/cinit-0.0.4/BUGS
new file mode 100644
index 00000000..dde5ba14
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/BUGS
@@ -0,0 +1,4 @@
+To be done before 0.1 (dirty release):
+- replace cerr-strings with #defines, so doubled strings are elimenated
+- remove all printf()s, as they are debug only
+- perhaps remove MAX_DEPS?
diff --git a/software/cinit/browse_source/cinit-0.0.4/COPYING b/software/cinit/browse_source/cinit-0.0.4/COPYING
new file mode 100644
index 00000000..3912109b
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/software/cinit/browse_source/cinit-0.0.4/CREDITS b/software/cinit/browse_source/cinit-0.0.4/CREDITS
new file mode 100644
index 00000000..fd3d6ff3
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/CREDITS
@@ -0,0 +1,14 @@
+--------------------------------------------------------------------------------
+Credits - People contributed to cinit
+Nico Schottelius, 2005-05-17
+--------------------------------------------------------------------------------
+
+The following list is sorted chronological, new contributors are
+added at the end of the list.
+
+
+René Nussbaumer
+ * helping with the general IPC idea
+ * testing and proof-reading code
+Marcus Przyklink
+ * coding linear lists, making MAX_SVC obsolete
diff --git a/software/cinit/browse_source/cinit-0.0.4/Changelog b/software/cinit/browse_source/cinit-0.0.4/Changelog
new file mode 100644
index 00000000..47142a97
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/Changelog
@@ -0,0 +1,8 @@
+Sun May 8 12:20:35 CEST 2005
+ *Changelog can now be found in monotone database (monotone log)
+Sat Apr 30 15:53:53 CEST 2005
+ * add socket code
+Tue Apr 26 15:29:53 CEST 2005
+ * removed is_cinit support, initial messaging framework
+Mon Apr 18 14:07:50 CEST 2005
+ * added is_cinit -> recognize if you are cinit or a fork
diff --git a/software/cinit/browse_source/cinit-0.0.4/MT/debug b/software/cinit/browse_source/cinit-0.0.4/MT/debug
new file mode 100644
index 00000000..c92ba837
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/MT/debug
@@ -0,0 +1,213 @@
+started up on Linux 2.6.11.10 #2 Tue May 17 11:58:45 CEST 2005 ppc
+command line: 'monotone-0.18', 'rename', 'conf/c_shd', 'conf/c_halt'
+set locale: LC_CTYPE=C, LC_MESSAGES=C
+initial path is /home/user/nico/cinit-0.0.4
+converting 13 bytes from ANSI_X3.4-1968 to UTF-8
+converting 6 bytes from ANSI_X3.4-1968 to UTF-8
+converting 10 bytes from ANSI_X3.4-1968 to UTF-8
+converting 11 bytes from ANSI_X3.4-1968 to UTF-8
+searching for 'MT' directory with root '/'
+search for 'MT' ended at '/home/user/nico/cinit-0.0.4' with '' removed
+initializing from directory /home/user/nico/cinit-0.0.4
+found working copy directory /home/user/nico/cinit-0.0.4
+options path is MT/options
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 7 bytes from UTF-8 to ANSI_X3.4-1968
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 7 bytes from UTF-8 to ANSI_X3.4-1968
+local dump path is MT/debug
+setting dump path to MT/debug
+opening rcfile '/home/user/nico/.monotonerc' ...
+'/home/user/nico/.monotonerc' is ok
+skipping nonexistent rcfile 'MT/monotonerc'
+executing rename command
+options path is MT/options
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 7 bytes from UTF-8 to ANSI_X3.4-1968
+revision path is MT/revision
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 8 bytes from UTF-8 to ANSI_X3.4-1968
+loading revision id from MT/revision
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 8 bytes from UTF-8 to ANSI_X3.4-1968
+db.fetch("SELECT id FROM 'revisions' WHERE id = '1f5c45fa438bfd4f2c0f851e985d51e983cffaaa'")
+db.fetch("SELECT data FROM revisions WHERE id = '1f5c45fa438bfd4f2c0f851e985d51e983cffaaa'")
+old manifest is c6e5abc9fa52a464b3984cae46232bfd43feaabd
+db.fetch("SELECT id FROM 'manifest_deltas' WHERE id = 'c6e5abc9fa52a464b3984cae46232bfd43feaabd'")
+db.fetch("SELECT id FROM 'manifests' WHERE id = 'c6e5abc9fa52a464b3984cae46232bfd43feaabd'")
+db.fetch("SELECT id FROM 'manifests' WHERE id = 'c6e5abc9fa52a464b3984cae46232bfd43feaabd'")
+db.fetch("SELECT data FROM 'manifests' WHERE id = 'c6e5abc9fa52a464b3984cae46232bfd43feaabd'")
+old manifest has 139 entries
+work path is MT/work
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 4 bytes from UTF-8 to ANSI_X3.4-1968
+checking for un-committed work file MT/work
+converting 2 bytes from UTF-8 to ANSI_X3.4-1968
+converting 4 bytes from UTF-8 to ANSI_X3.4-1968
+read rearrangement from MT/work
+'conf/c_shd' prefixed to 'conf/c_shd'
+'conf/c_halt' prefixed to 'conf/c_halt'
+analyzing file 1 : '' -> 'BUGS'
+analyzing file 2 : '' -> 'CREDITS'
+analyzing file 3 : '' -> 'Changelog'
+analyzing file 4 : '' -> 'Makefile'
+analyzing file 5 : '' -> 'README'
+analyzing file 6 : '' -> 'TODO'
+analyzing file 8 : '' -> 'bin/cinit.add.dependency'
+analyzing file 9 : '' -> 'bin/cinit.add.getty'
+analyzing file 10 : '' -> 'bin/cinit.create.cinit_dir'
+analyzing file 11 : '' -> 'bin/cinit.create.empty.service'
+analyzing file 12 : '' -> 'bin/cinit.do.not.respawn.service'
+analyzing file 13 : '' -> 'bin/cinit.mkheader'
+analyzing file 14 : '' -> 'bin/cinit.remove.getty'
+analyzing file 15 : '' -> 'bin/cinit.respawn.service'
+analyzing file 16 : '' -> 'bin/cinit.shutdown'
+analyzing file 17 : '' -> 'bin/cinit.read-conf'
+analyzing file 18 : '' -> 'cinit.h'
+analyzing file 20 : '' -> 'client/begin_msg.c'
+analyzing file 21 : '' -> 'client/connect_sock.c'
+analyzing file 22 : '' -> 'client/exec_svc.c'
+analyzing file 23 : '' -> 'client/kill_svc.c'
+analyzing file 24 : '' -> 'client/msg_change_status.c'
+analyzing file 25 : '' -> 'client/msg_start_svc.c'
+analyzing file 26 : '' -> 'client/respawn_svc.c'
+analyzing file 27 : '' -> 'client/run_run_svc.c'
+analyzing file 28 : '' -> 'client/run_svc.c'
+analyzing file 30 : '' -> 'comm/do_change_status.c'
+analyzing file 31 : '' -> 'comm/do_result.c'
+analyzing file 32 : '' -> 'comm/do_start_svc.c'
+analyzing file 34 : '' -> 'conf/c_env'
+analyzing file 35 : '' -> 'conf/c_init'
+analyzing file 36 : '' -> 'conf/c_needs'
+analyzing file 37 : '' -> 'conf/c_off'
+analyzing file 38 : '' -> 'conf/c_on'
+analyzing file 39 : '' -> 'conf/c_params'
+analyzing file 40 : '' -> 'conf/c_reboot'
+analyzing file 41 : '' -> 'conf/c_respawn'
+analyzing file 42 : '' -> 'conf/c_shd'
+analyzing file 43 : '' -> 'conf/c_sock'
+analyzing file 44 : '' -> 'conf/c_tmp'
+analyzing file 45 : '' -> 'conf/c_tmpfs'
+analyzing file 46 : '' -> 'conf/c_tmpmount'
+analyzing file 47 : '' -> 'conf/c_wants'
+analyzing file 48 : '' -> 'conf/cinit_dir'
+analyzing file 49 : '' -> 'conf/destdir'
+analyzing file 50 : '' -> 'conf/getty_dir'
+analyzing file 51 : '' -> 'conf/sleep_svc'
+analyzing file 52 : '' -> 'conf/sock_group'
+analyzing file 53 : '' -> 'conf/sock_mode'
+analyzing file 54 : '' -> 'conf/sock_queue'
+analyzing file 55 : '' -> 'conf/sock_user'
+skipping preserved file 57 : ''
+analyzing file 58 : '' -> 'doc/caveats'
+analyzing file 59 : '' -> 'doc/cinit.commands'
+analyzing file 61 : '' -> 'doc/fun/testing01'
+analyzing file 62 : '' -> 'doc/how_it_works_internally'
+analyzing file 63 : '' -> 'doc/ipc.thoughts'
+analyzing file 64 : '' -> 'doc/ipc.usenet.posting'
+analyzing file 65 : '' -> 'doc/posix.aardvark.bug.report'
+analyzing file 66 : '' -> 'doc/shutting.down'
+analyzing file 67 : '' -> 'doc/thoughts.closed'
+analyzing file 68 : '' -> 'doc/thoughts.open'
+analyzing file 70 : '' -> 'generic/mini_printf.c'
+analyzing file 71 : '' -> 'generic/set_signals.c'
+analyzing file 73 : '' -> 'old/cerr.c'
+analyzing file 74 : '' -> 'old/cinit.c01'
+analyzing file 75 : '' -> 'old/cinit.c02'
+analyzing file 76 : '' -> 'old/cinit.c03'
+analyzing file 77 : '' -> 'old/cinit.c04'
+analyzing file 78 : '' -> 'old/cinit.c05'
+analyzing file 79 : '' -> 'old/cinit.c06'
+analyzing file 80 : '' -> 'old/cinit.commands.v01'
+analyzing file 81 : '' -> 'old/cinit.h01'
+analyzing file 82 : '' -> 'old/cnt_digits.c'
+analyzing file 83 : '' -> 'old/do_change_status.c01'
+analyzing file 84 : '' -> 'old/idea01'
+analyzing file 85 : '' -> 'old/idea02'
+analyzing file 86 : '' -> 'old/msg_change_status.c01'
+analyzing file 87 : '' -> 'old/msg_start_svc.c'
+analyzing file 88 : '' -> 'old/run_init_svc.c01'
+analyzing file 89 : '' -> 'old/run_svc.c00'
+analyzing file 90 : '' -> 'old/run_svc.c01'
+analyzing file 91 : '' -> 'old/run_svc.c02'
+analyzing file 92 : '' -> 'old/run_svc.c03'
+analyzing file 93 : '' -> 'old/run_svc.c04'
+analyzing file 94 : '' -> 'old/run_svc.c05'
+analyzing file 95 : '' -> 'old/run_svc.c05.2'
+analyzing file 96 : '' -> 'old/run_svc.c06'
+analyzing file 97 : '' -> 'old/run_svc.c07'
+analyzing file 98 : '' -> 'old/run_svc.c08'
+analyzing file 99 : '' -> 'old/run_svc.c09'
+analyzing file 100 : '' -> 'old/sig_chld.c'
+analyzing file 101 : '' -> 'old/sigio.c01'
+analyzing file 103 : '' -> 'sbin/cinit'
+analyzing file 105 : '' -> 'serv/add_mod_svc.c'
+analyzing file 106 : '' -> 'serv/chk_svc.c'
+analyzing file 107 : '' -> 'serv/cinit.c'
+analyzing file 108 : '' -> 'serv/list.c'
+analyzing file 109 : '' -> 'serv/panic.c'
+analyzing file 110 : '' -> 'serv/run_init_svc.c'
+analyzing file 111 : '' -> 'serv/sig_reboot.c'
+analyzing file 112 : '' -> 'serv/sigio.c'
+analyzing file 114 : '' -> 'size/2005-04-26-14:54:44'
+analyzing file 115 : '' -> 'size/2005-04-26-16:47:50'
+analyzing file 116 : '' -> 'size/2005-04-26-16:48:48'
+analyzing file 117 : '' -> 'size/2005-04-26-16:50:45'
+analyzing file 118 : '' -> 'size/2005-04-26-17:12:48'
+analyzing file 119 : '' -> 'size/2005-04-26-17:13:43'
+analyzing file 120 : '' -> 'size/2005-04-26-23:05:33'
+analyzing file 121 : '' -> 'size/2005-04-27-00:39:24'
+analyzing file 122 : '' -> 'size/2005-04-30-15:18:22'
+analyzing file 123 : '' -> 'size/2005-04-30-15:20:40'
+analyzing file 124 : '' -> 'size/2005-04-30-15:23:25'
+analyzing file 125 : '' -> 'size/2005-04-30-15:25:44'
+analyzing file 126 : '' -> 'size/2005-04-30-15:32:43'
+analyzing file 127 : '' -> 'size/2005-04-30-15:33:37'
+analyzing file 128 : '' -> 'size/2005-04-30-15:41:08'
+analyzing file 129 : '' -> 'size/2005-04-30-15:41:18'
+analyzing file 130 : '' -> 'size/2005-04-30-15:46:09'
+analyzing file 131 : '' -> 'size/2005-04-30-16:48:16'
+analyzing file 132 : '' -> 'size/2005-04-30-16:50:05'
+analyzing file 133 : '' -> 'size/2005-04-30-17:02:27'
+analyzing file 134 : '' -> 'size/2005-04-30-17:03:00'
+analyzing file 135 : '' -> 'size/2005-04-30-17:05:11'
+analyzing file 136 : '' -> 'size/2005-04-30-17:06:15'
+analyzing file 137 : '' -> 'size/2005-04-30-17:11:59'
+analyzing file 138 : '' -> 'size/2005-04-30-17:13:43'
+analyzing file 139 : '' -> 'size/2005-04-30-22:28:13'
+analyzing file 140 : '' -> 'size/2005-04-30-22:34:23'
+analyzing file 141 : '' -> 'size/2005-05-02-13:27:51'
+analyzing file 142 : '' -> 'size/2005-05-02-13:46:31'
+analyzing file 143 : '' -> 'size/2005-05-02-13:49:29'
+analyzing file 144 : '' -> 'size/2005-05-02-13:49:58'
+analyzing file 145 : '' -> 'size/2005-05-02-13:52:20'
+analyzing file 146 : '' -> 'size/2005-05-02-13:55:50'
+analyzing file 147 : '' -> 'size/2005-05-02-13:58:14'
+analyzing file 148 : '' -> 'size/2005-05-02-13:59:53'
+analyzing file 149 : '' -> 'size/2005-05-02-14:00:26'
+analyzing file 150 : '' -> 'size/2005-05-02-14:04:19'
+skipping preserved directory 151 : 'bin'
+skipping preserved directory 152 : 'client'
+skipping preserved directory 153 : 'comm'
+skipping preserved directory 154 : 'conf'
+skipping preserved directory 155 : 'doc'
+skipping preserved directory 156 : 'doc/fun'
+skipping preserved directory 157 : 'generic'
+skipping preserved directory 158 : 'old'
+skipping preserved directory 159 : 'sbin'
+skipping preserved directory 160 : 'serv'
+skipping preserved directory 161 : 'size'
+analyzing file 168 : '' -> 'bin/cinit.add.shutdown.reboot.poweroff'
+analyzing file 169 : '' -> 'bin/cinit.get-confdir'
+analyzing file 171 : '' -> 'bin/not-working/cinit.create.service'
+analyzing file 173 : '' -> 'conf/.README'
+analyzing file 174 : '' -> 'conf/c_halt'
+analyzing file 175 : '' -> 'conf/c_poweroff'
+analyzing file 176 : '' -> 'conf/sleep_kill'
+analyzing file 178 : '' -> 'doc/.buildwarn'
+analyzing file 179 : '' -> 'doc/meta.dependencies'
+skipping preserved directory 180 : 'bin/not-working'
+adding conf/c_shd -> conf/c_halt to working copy rename set
+skipping preserved directory 1 : 'conf'
+analyzing file 2 : 'conf/c_shd' -> 'conf/c_halt'
+change_set.cc:565: invariant 'I(entries.find(p) == entries.end())' violated
diff --git a/software/cinit/browse_source/cinit-0.0.4/MT/log b/software/cinit/browse_source/cinit-0.0.4/MT/log
new file mode 100644
index 00000000..e69de29b
diff --git a/software/cinit/browse_source/cinit-0.0.4/MT/options b/software/cinit/browse_source/cinit-0.0.4/MT/options
new file mode 100644
index 00000000..33960254
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/MT/options
@@ -0,0 +1,3 @@
+ branch "info.clinux.cinit"
+database "/home/user/nico/monotone.db"
+ key ""
diff --git a/software/cinit/browse_source/cinit-0.0.4/MT/revision b/software/cinit/browse_source/cinit-0.0.4/MT/revision
new file mode 100644
index 00000000..9b3e32e6
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/MT/revision
@@ -0,0 +1 @@
+81778a4d16c2b27a8e686600dde41795fc5ed6b8
diff --git a/software/cinit/browse_source/cinit-0.0.4/Makefile b/software/cinit/browse_source/cinit-0.0.4/Makefile
new file mode 100644
index 00000000..6726f177
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/Makefile
@@ -0,0 +1,83 @@
+#
+# cinit
+# Nico Schottelius
+#
+# Don't edit Makefile, use conf/*.
+#
+
+#
+# compile/link options
+#
+# do not use DEBUG and OPTIMIZE at the same time!
+#DEBUG=-g -DDEBUG
+OPTIMIZE=-Os
+LDFLAGS=-static # init should be static per default!
+
+# programs
+CC=gcc $(DEBUG) $(OPTIMIZE)
+CFLAGS=-pipe -Wall -I.
+LD=gcc
+STRIP=strip
+
+# monotone
+MT=monotone-0.18
+
+# directories and files
+DIRS=client bin conf comm generic doc sbin serv
+FILES=BUGS Changelog Makefile README TODO cinit.h
+
+# objects
+SERV=serv/sigio.o serv/cinit.o serv/list.o \
+ serv/run_init_svc.o serv/panic.o serv/sig_reboot.o
+
+CLIENT=client/msg_start_svc.o client/msg_change_status.o client/run_svc.o \
+ client/exec_svc.o client/respawn_svc.o client/run_run_svc.o \
+ client/connect_sock.o client/begin_msg.o
+
+COMMUNICATION=comm/do_change_status.o comm/do_result.o comm/do_start_svc.o
+
+BOTH=generic/set_signals.o generic/mini_printf.o
+
+OBJ=$(SERV) $(CLIENT) $(BOTH) $(COMMUNICATION)
+
+# DO NOT CHANGE THIS.
+SBIN=sbin
+CINIT_BIN=$(SBIN)/cinit
+
+# targets
+warn:
+ @cat doc/.buildwarn
+
+all: $(CINIT_BIN) sizecheck
+
+$(CINIT_BIN): $(SBIN) config.h $(OBJ)
+ $(LD) $(LDFLAGS) $(OBJ) -o $@
+ $(STRIP) $@
+$(SBIN):
+ mkdir $(SBIN)
+sizecheck:
+ FILE="size/`date +%Y-%m-%d-%T`"; ls -l sbin/cinit > $$FILE; cat $$FILE
+clean:
+ rm -f *.o */*.o sbin/cinit config.h
+config.h: conf/*
+ ./bin/cinit.mkheader > config.h
+
+mt-update:
+ $(MT) add $(DIRS) $(FILES) 2>/dev/null
+mt-commit:
+ $(MT) commit
+mt-sync:
+ $(MT) sync linux.schottelius.org info.clinux.cinit
+
+install:
+ chmod 0700 ./scripts/install
+ ./bin/cinit.install.binary
+# rm /sbin/cinit
+# cp sbin/cinit /sbin/cinit
+
+install-conf:
+ @echo *** Creating very basic configuration. ***
+ ./bin/cinit.install.conf
+install-test:
+ @echo *** Copying testing configuration. ***
+ ./bin/cinit.install.test
diff --git a/software/cinit/browse_source/cinit-0.0.4/README b/software/cinit/browse_source/cinit-0.0.4/README
new file mode 100644
index 00000000..54da5376
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/README
@@ -0,0 +1,92 @@
+--------------------------------------------------------------------------------
+cinit, Nico Schottelius, 2005-04-28 [last change: 2005-05-07]
+--------------------------------------------------------------------------------
+
+Introduction
+============
+
+cinit is a fast init system with dependency features.
+It is orientated on the design off Richard Gooch's
+need [0] and Felix von Leitner's minit[1]. Minit does not support real
+dependencies (you don't know whether the service you depend on really
+started) and the need concept is somehow slow (as seen in gentoo).
+In addition, minit needs libowfat and dietlibc, which may not be found
+on every Unix system.
+
+cinit main features:
+- portability: it should run on every POSIX compatible system.
+- true dependencies
+- parallel execution
+- highly customisable (see conf/*)
+
+
+Getting cinit
+=============
+
+This README is part of the source, so you should have it.
+If not, goto the homepage [2] and download the tar archive
+or get the lastest snapshot via monotone.
+
+
+Pre-Configuring
+===============
+
+If you want to fine tune cinit parameters, add different path names,
+change the DESTDIR, ... have a look at conf/*.
+
+
+Installing
+==========
+
+You can install cinit parallel to any other init-system, it won't
+kill other init's config nor /sbin/init, if it exists.
+
+You only have to tell your kernel to execute /sbin/cinit instead
+of /sbin/init.
+
+Everybody do:
+# make all install
+
+If it's the first time you operate with cinit, also do:
+# make install-example
+
+This will populate /etc/cinit with some default services for Linux
+(mounting root r/w, starting gettys, setting hostname).
+
+This should work on most Linux systems, still you should have a
+look at /etc/cinit and see whether services are correct.
+
+
+Configuring
+===========
+
+You'll have to configure /etc/cinit and add your existing services.
+
+Please read doc/configuring.cinit for details.
+
+sampleconfig.tar is the tar-ball I used for testing, beware if you use it:
+It loads dvorak at startup!
+
+There are currently no tools to merge your existing init-system
+to cinit (like sysvinit-merge, bsd-merge or minit-merge) available.
+If someone cares and tries to do that, I would be happy to include
+the script(s).
+
+Additionally I would be thankful for tar-balls containing a complete
+replacement of $your_unix_init.
+
+
+Author, Contact, Bug reports, etc.
+==================================
+Nico Schottelius (nico-linux-cinit<>schottelius [[dot]] org) is the
+author. Bug reports should be send to this address.
+
+The homepage of cinit is [2].
+
+
+References:
+===========
+
+[0]: need: http://www.atnf.csiro.au/people/rgooch/linux/boot-scripts/
+[1]: minit: http://www.fefe.de/minit/
+[2]: cinit: http://linux.schottelius.org/cinit.html
diff --git a/software/cinit/browse_source/cinit-0.0.4/TODO b/software/cinit/browse_source/cinit-0.0.4/TODO
new file mode 100644
index 00000000..049a0bbc
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/TODO
@@ -0,0 +1,66 @@
+- check return values of most functions!
+- check errno!
+- check whether headers are ok
+- remove printfs!
+- write manpages (use doc/* as base for that)
+- eventually split cinit code to csvc to minimize binary of cinit?
+- cleanup comments
+- cleanup headers!
+- respawn_svc and exec_svc must return pid_t of executed service / watcher
+- exec_svc.c: should we also change environment?
+- write install-example for non-Linux systems (think of merge also)
+- move messages to cinit.h or message.h or conf/msg-*!
+- remove MAX_SVC
+- change exec_svc to be much more dumb!
+ *svc, *svc_param_file, *svc_env_file
+- remove stat from exec_svc, do before!
+- check for possibilies to save ram, free things
+- stat() in run_svc -> don't call exec_svc, respawn_svc, run_run_svc
+- close(*>2) before forking / executing
+- get CTR-ALT-DEL
+- check if we caught every signal, which could kill us
+- create coala-socket with correct permissions! (550, root:cinit)
+
+- run_svc_new:
+ o we have many strcat()s, perhaps save length of pathbuf and strncat at
+ pathtmp[strlen(pathbuf)] ?
+ o should we check strcat and strcpy return values or do we expect them to work?
+
+--------------------------------------------------------------------------------
+
+- script merge sysVinit to cinit?
+- circulaere abhaengigkeiten?
+ - script vorher?
+
+--------------------------------------------------------------------------------
+
+- create conversion table:
+ djbdns <-> name_server
+ dnscache <-> name_caching
+ qmail,postfix,... <-> MTA
+
+--------------------------------------------------------------------------------
+create_mini_cinit
+ -> create something which should be runnable
+ -> mount, fsck, getty
+ --> for dev in `read /etc/fstab` ...
+ fsck $dev
+ --> mount -a
+ --> mount -n -o remount,rw /
+ --> getty from /etc/inittab or /sbin/*getty
+ -> find out, which gettys with which params
+ -> use it on 'make install'
+--------------------------------------------------------------------------------
+
+signal handlers:
+sa.sa_handler=sigint; sigaction(SIGINT,&sa,0); /* ctrl-alt-del */
+sa.sa_handler=sigwinch; sigaction(SIGWINCH,&sa,0); /* keyboard request */
+
+--------------------------------------------------------------------------------
+
+Add support for 'cinit' group, which may shutdown/reboot/halt with
+SO_PASSCRED in sockets
+
+--------------------------------------------------------------------------------
+Done
+- include '/' in C_RUNS? make double strings? -> no.
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.add.dependency b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.add.dependency
new file mode 100644
index 00000000..17683dcc
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.add.dependency
@@ -0,0 +1,41 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create dependency: service a needs or wants service b
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+
+if [ $# -ne 3 ]; then
+ echo "`basename $0`: service_A [wants|needs] service_B"
+ echo ""
+ echo " Service A needs or needs Service B."
+ echo " Use relative paths, not absolute."
+ echo " You must specify whether to use wants or needs."
+ echo ""
+ exit 23
+fi
+
+SVC_A=$1
+DEP=$2
+SVC_B=$3
+
+case $DEP in
+ wants) DEP=$C_WANTS ;;
+ needs) DEP=$C_NEEDS ;;
+ *) echo "Did not I say \"want\" or \"need\"? You _must_ use those terms."
+esac
+
+# FIXME: could some PLEASE simply that?
+SLASHES=$(echo $SVC_A | sed -e 's,/$,,' -e 's,[^/],,g' -e 's,/,../,g' -e 's,^,../../,')
+DEST_NAME=$(echo $SVC_B | sed -e 's,/$,,' -e 's,/,-,g')
+
+SOURCE="${SLASHES}${SVC_B}"
+DEST="${BASEDIR}/${SVC_A}/${DEP}/${DEST_NAME}"
+
+echo -n "Linking $SOURCE to $DEST ... "
+ln -sf "$SOURCE" "$DEST"
+echo "finished."
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.add.getty b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.add.getty
new file mode 100644
index 00000000..2c97d607
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.add.getty
@@ -0,0 +1,60 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create gettys
+# 2005-05-24
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+BASEDIR=$DESTDIR/$CINIT_DIR/$GETTY_DIR
+LAST_NUMBER=$(cd $BASEDIR && echo * | sed 's/.* //')
+NUMBER=$(echo $LAST_NUMBER + 1 | bc)
+
+[ ! "$NUMBER" ] && NUMBER=1
+
+DDIR=$BASEDIR/$NUMBER
+
+echo "Creating getty number $NUMBER in $DDIR ..."
+
+if [ "$USE_THIS_GETTY" ]; then
+ GETTYS="$USE_THIS_GETTY"
+else
+ GETTYS=`echo /sbin/*getty*`
+fi
+
+for getty in $GETTYS; do
+ case $getty in
+ */fgetty|*/mingetty)
+ mygetty=$getty
+ params="/dev/tty${NUMBER}"
+ ;;
+ */agetty|*/getty)
+ mygetty=$getty
+ params="38400 tty${NUMBER} linux"
+ ;;
+ *)
+ echo "Unknown Getty type $getty"
+ echo "Please report standard parameters to me."
+ esac
+
+ [ "$mygetty" ] && break
+done
+
+if [ ! "$mygetty" ]; then
+ echo "No useable getty found, existing."
+ exit 1
+fi
+
+echo -n "Using $mygetty $params ... "
+mkdir -p "$DDIR"
+ln -s $mygetty "$DDIR/$C_ON"
+
+for param in $params; do
+ echo $param >> "$DDIR/${C_ON}${C_PARAMS}"
+done
+
+touch "$DDIR/$C_RESPAWN"
+
+echo "finished."
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.create.empty.service b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.create.empty.service
new file mode 100644
index 00000000..9fe748d8
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.create.empty.service
@@ -0,0 +1,43 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create templates
+# 2005-05-24
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+if [ $# -lt 1 ]; then
+ echo "`basename $0`: service-name(s)"
+ echo " I do create templates for your services"
+ exit 1
+fi
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+BASEDIR=./testcinit
+
+
+for svc in $@; do
+ INSTDIR=${BASEDIR}/${svc}
+ if [ -e "$INSTDIR" ]; then
+ echo "$svc already exists, skipping."
+ continue
+ fi
+ echo -n "Creating $svc ..."
+ # install creates needed parent directories
+ "$INSTALL_PROG" "$INSTALL_DIRECTORY" "${INSTDIR}/${C_NEEDS}"
+ echo "The services this services really needs (it will not start if one failed to start)." > "${INSTDIR}/${C_NEEDS}/README"
+ "$INSTALL_PROG" "$INSTALL_DIRECTORY" "${INSTDIR}/${C_WANTS}"
+ echo "The services this services wants (it will start if one or more fail)." > "${INSTDIR}/${C_WANTS}/README"
+
+ echo '#!/bin/sh' > "${INSTDIR}/${C_ON}"
+ echo "echo This should be a link to an executable or a script" >> "${INSTDIR}/${C_ON}"
+ chmod 0700 "${INSTDIR}/${C_ON}"
+ echo "One paramater on each line." > "${INSTDIR}/${C_ON}${C_PARAMS}"
+ echo "Delete me, if there are no paramaters." > "${INSTDIR}/${C_ON}${C_PARAMS}"
+ echo "Environtment: varx=valuex, one variable on each line." > "${INSTDIR}/${C_ON}${C_ENV}"
+ echo "Delete me, if you do not want to set any variables." > "${INSTDIR}/${C_ON}${C_ENV}"
+ echo "finished."
+done
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.do.not.respawn.service b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.do.not.respawn.service
new file mode 100644
index 00000000..4b102477
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.do.not.respawn.service
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: switch respawning off
+# 2005-05-24
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+if [ $# -lt 1 ]; then
+ echo "`basename $0`: service-name(s)"
+ echo " The respawning mark will be removed from services"
+ exit 1
+fi
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+
+for svc in $@; do
+ echo -n "Removing respawning mark from $svc ..."
+ rm -f "${BASEDIR}/${svc}/${C_RESPAWN}"
+ echo "finished."
+done
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.get-confdir b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.get-confdir
new file mode 100644
index 00000000..a36c52f9
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.get-confdir
@@ -0,0 +1,18 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: read configuration into variables
+# 2005-05-24
+
+# try environment first
+if [ "$CINIT_DIR" ]; then
+ CONFDIR=$CINIT_DIR
+elif [ -d $(dirname $0)/../conf/ ]; then
+ CONFDIR=$(dirname $0)/../conf/
+elif [ -d /etc/cinit ]; then
+ CONFDIR=/etc/cinit
+else
+ echo Did not find cinit configuration 1>&2
+ exit 1
+fi
+
+echo $CONFDIR
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.install.binary b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.install.binary
new file mode 100644
index 00000000..4d447257
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.install.binary
@@ -0,0 +1,10 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: install basic setup
+#
+
+
+. $(dirname $0)/cinit.read-conf
+
+"$INSTALL_PROG" sbin/cinit $DESTDIR/$PREFIX/sbin/cinit
+"$INSTALL_PROG" "$INSTALL_DIRECTORY" $DESTDIR/$PREFIX/$CINIT_DIR
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.mkheader b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.mkheader
new file mode 100644
index 00000000..e1f35d07
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.mkheader
@@ -0,0 +1,20 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create header file
+#
+
+
+CONFS=$($(dirname $0)/cinit.get-confdir)/../conf/*
+
+echo "/* Warning: Autogenerated by $0, do not edit. */"
+for conf in $CONFS; do
+ NAME="$(basename $conf | tr a-z A-Z)"
+ value=$(head -n 1 $conf)
+
+ # check if numeric - no I didn't see an easier way
+ numeric=$(echo $value | awk '/^((0[xX])[0-9a-fA-F]+)|([0-9]+)$/ { print }')
+
+ [ "$numeric" ] || value="\"$value\""
+
+ echo "#define" "$NAME" "$value"
+done
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.read-conf b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.read-conf
new file mode 100644
index 00000000..4263129c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.read-conf
@@ -0,0 +1,13 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: read configuration into variables
+#
+
+CONFS=$($(dirname $0)/cinit.get-confdir)/../conf/*
+
+for conf in $CONFS; do
+ NAME="$(basename $conf | tr a-z A-Z)"
+ eval $NAME="$(head -n 1 $conf)"
+ eval export $NAME
+# eval echo $NAME = \$$NAME
+done
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.remove.getty b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.remove.getty
new file mode 100644
index 00000000..5a885725
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.remove.getty
@@ -0,0 +1,22 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create gettys
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+BASEDIR=$DESTDIR/$CINIT_DIR/$GETTY_DIR
+NUMBER=$(cd $BASEDIR; echo * | sed 's/.* //')
+
+[ ! "$NUMBER" ] && exit 1
+
+DDIR=$BASEDIR/$NUMBER
+
+echo "Removing getty number $NUMBER located in $DDIR ..."
+read -p "Are you sure [y/N]? " yes
+
+if [ "$yes" = "y" ]; then
+ rm -r $DDIR
+else
+ echo "Aborted."
+fi
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.respawn.service b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.respawn.service
new file mode 100644
index 00000000..35ac7932
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.respawn.service
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: switch respawning on
+# 2005-05-24
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+if [ $# -lt 1 ]; then
+ echo "`basename $0`: service-name(s)"
+ echo " Services will be marked respawning"
+ exit 1
+fi
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+
+for svc in $@; do
+ echo -n "Marking $svc respawning ..."
+ touch "${BASEDIR}/${svc}/${C_RESPAWN}"
+ echo "finished."
+done
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/cinit.shutdown b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.shutdown
new file mode 100644
index 00000000..49b1dabd
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/cinit.shutdown
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Nico Schottelius
+# shutdown system
+# 2005-05-24
+
+
+usage()
+{
+ echo "`basename $0` -[ohr]"
+ echo " Shutdown the system:"
+ echo " -o|--off: Power off"
+ echo " -h|--halt: Halt"
+ echo " -r|--reboot: Reboot"
+ echo " "
+ exit 1
+}
+
+if [ $# -ne 1 ]; then
+ usage
+fi
+
+case $1 in
+ -r|--reboot) kill -HUP 1 ;;
+ -o|--off) kill -TERM 1 ;;
+ -h|--halt) kill -USR1 1 ;;
+ *) usage ;;
+esac
diff --git a/software/cinit/browse_source/cinit-0.0.4/bin/not-working/cinit.create.service b/software/cinit/browse_source/cinit-0.0.4/bin/not-working/cinit.create.service
new file mode 100644
index 00000000..df092275
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/bin/not-working/cinit.create.service
@@ -0,0 +1,40 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create templates
+# 2005-05-24
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+if [ $# -lt 1 ]; then
+ echo "`basename $0`: service-name (including category)"
+ echo " I do create a service for you"
+ exit 1
+fi
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+
+# read input (from gentoo-bug.sh, http://linux.schottelius.org/scripts/#gentoo-bug
+reread()
+{
+ _tmp=""
+ name="$1"
+
+ while [ ! "$_tmp" ]; do
+ read -p "$1 [$_tmp]: " _tmp
+ done
+
+ echo $_tmp
+}
+
+
+for svc in $@; do
+ echo -n "Creating $svc ..."
+ mkdir -p "${BASEDIR}/${svc}"
+ cd ${BASEDIR}/${svc}
+ mkdir -p "${C_WANTS}" "${C_NEEDS}"
+ echo "finished."
+done
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/cinit.h b/software/cinit/browse_source/cinit-0.0.4/cinit.h
new file mode 100644
index 00000000..353071be
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/cinit.h
@@ -0,0 +1,129 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * header of cinit
+ */
+
+/* includes */
+#include /* pid_t */
+#include "config.h" /* paths, socket options, etc. */
+
+/* limits: will be obsolete in cinit-1.0 */
+#define MAX_SVC 510 /* maximum services - defines size of array - may later be obsoleted */
+#define MAX_DEPS 32 /* maximum direct dependencies of a service */
+#define BUFSIZE 4096
+
+/* paths */
+#define C_ONARG C_ON C_PARAMS
+#define C_OFFARG C_OFF C_PARAMS
+#define C_ONENV C_ON C_ENV
+#define C_OFFENV C_OFF C_ENV
+
+#define SLASH "/"
+
+#define CINIT_INIT CINIT_DIR SLASH C_INIT
+#define CINIT_TMNT CINIT_DIR SLASH C_TMP
+#define CINIT_SOCK CINIT_TMNT SLASH C_SOCK
+
+/* commands (maximum: 2^8 = 256)*/
+#define CMD_START_SVC 0
+#define CMD_CHG_STATUS 1
+#define CMD_STOP_SVC 2
+#define CMD_KILL_SVC 3
+
+#define CMD_RESCUE 251
+#define CMD_INIT 252
+
+#define CMD_HALT 253
+#define CMD_REBOOT 254
+#define CMD_POWEROFF 255
+
+/* status of a service */
+#define ST_TMP 1 /* currently working on it */
+#define ST_ONCE 2 /* executed once */
+#define ST_RESPAWN 3 /* running and respawning */
+#define ST_FAIL 4 /* failed to start service */
+
+/* actions for i/o handlers (see comm/do_*) */
+#define ACT_SERV 0
+#define ACT_CLIENT 1
+
+/* Messages to the outside */
+
+#define MSG_ERR_FORK "fork"
+#define MSG_ERR_EXECVE "execve"
+#define MSG_ERR_ALLOC "memory allocation"
+#define MSG_ERR_UMOUNT "umount"
+#define MSG_TERMKILL "sigterm"
+#define MSG_KILLBILL "sigkill"
+
+/* array of svc - not needed anymore
+struct svc {
+ char *abs_path; * service identifier *
+ char status; * tmp, respawn, ran once *
+ pid_t pid; * pid of the process *
+};
+
+struct svcl {
+ struct svc svca[MAX_SVC];
+ int process;
+};
+*/
+
+// extern struct svcl svc_list;
+struct listitem {
+ char *abs_path;
+ int status;
+ pid_t pid;
+ struct listitem *before;
+ struct listitem *after;
+};
+
+
+/* variables */
+extern struct listitem *list;
+extern int sock, logfd;
+
+/* functions (used by server and client) */
+void cerr(char *string, int status);
+int run_svc(char *rpath);
+void mini_printf(char *str, int fd);
+void set_signals(int action);
+#define LOG(s) mini_printf(s,logfd)
+
+int do_start_svc(int sock2, char *svc, int action);
+int do_change_status(char *svc, char *status, pid_t *pid, int sock2, int action);
+char do_result(int sock2, char *value);
+
+/* server functions */
+/* int chk_svc(char *svc);
+int add_mod_svc(char *svc, char status, pid_t pid); */
+int list_insert(char *path, int status);
+struct listitem *list_search(char *path);
+int list_delete(char *path);
+int run_init_svc(void);
+void sigio(int signal);
+void sig_reboot(int signal);
+void panic(void);
+
+/* client / message functions */
+int msg_start_svc(char *svc);
+int msg_change_status(char *svc, char status, pid_t pid);
+int begin_msg(char cmd);
+
+/* client functions */
+int run_run_svcs(char *abspath);
+pid_t exec_svc(char *abspath, int on);
+pid_t respawn_svc(char *abspath);
+int connect_sock(int socke);
+char **read_file(char *file);
+
+
+/* DEBUG */
+#ifdef DEBUG
+# define D_PRINTF(x) ( printf("[%s:%d]: %s\n",__FILE__,__LINE__,x) )
+#else
+# define D_PRINTF(x) if(0)
+#endif
+
+/* Messages to the outside */
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/README b/software/cinit/browse_source/cinit-0.0.4/client/README
new file mode 100644
index 00000000..0a5b8d0c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/README
@@ -0,0 +1,2 @@
+client/
+ These sources are used by the children which are spawned by cinit.
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/begin_msg.c b/software/cinit/browse_source/cinit-0.0.4/client/begin_msg.c
new file mode 100644
index 00000000..9b569543
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/begin_msg.c
@@ -0,0 +1,24 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * tell cinit that I want to start a service
+ * part of cinit
+ */
+
+#include
+#include
+#include "cinit.h"
+
+int begin_msg(char cmd)
+{
+ sock = connect_sock(sock);
+ if( sock == -1 ) {
+ return 0;
+ }
+
+ if(write(sock,&cmd,sizeof(cmd)) == -1) {
+ perror("i/o: command");
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/connect_sock.c b/software/cinit/browse_source/cinit-0.0.4/client/connect_sock.c
new file mode 100644
index 00000000..831121b7
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/connect_sock.c
@@ -0,0 +1,41 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+/* open socket connection to cinit-serv and close original socket */
+int connect_sock(int socke)
+{
+ int nsock;
+ struct sockaddr_un addr;
+
+ D_PRINTF("socket verbinden");
+
+ /******************* begin socket *********************/
+ close(socke);
+
+ nsock = socket(PF_UNIX,SOCK_STREAM,0);
+ if( nsock == -1 ) {
+ perror("socket");
+ return -1;
+ }
+ socke = sizeof(addr);
+ memset(&addr,0,socke);
+ strcpy(addr.sun_path, CINIT_SOCK);
+ addr.sun_family = AF_UNIX;
+
+ if(connect(nsock,(struct sockaddr *)&addr,socke) == -1) {
+ perror("connect");
+ return -1;
+ }
+
+ return nsock;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/exec_svc.c b/software/cinit/browse_source/cinit-0.0.4/client/exec_svc.c
new file mode 100644
index 00000000..bdbe53f8
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/exec_svc.c
@@ -0,0 +1,246 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/***********************************************************************
+ * exec_svc: exec service abspath C_ON or C_OFF
+ */
+
+pid_t exec_svc(char *abspath, int on)
+{
+ pid_t pid;
+ int tmp;
+ char *p, pathtmp[PATH_MAX];
+ char *sbuf = NULL, **nargv = NULL, **nenv = NULL;
+ int fd, argc;
+ struct stat buf;
+
+ pid = fork();
+ if( pid == -1 ) {
+ perror("fork");
+ return 0;
+ }
+
+ /***** PARENT ******/
+ if(pid > 0) {
+ waitpid(pid,&tmp,0);
+ if( WIFEXITED(tmp) ) {
+ D_PRINTF("EXEC SVC ERFOLGREICH");
+ return pid;
+ } else {
+ D_PRINTF("EXEC SVC FEHLGESCHLAGEN");
+ return 0;
+ }
+ }
+
+ /*********** CHILD EXECUTION ***********/
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+
+ if(on) {
+ strcat(pathtmp,C_ON);
+ } else {
+ strcat(pathtmp,C_OFF);
+ }
+
+ D_PRINTF(pathtmp);
+
+ /* readlink retrieves real name, if it is a symlink */
+ if ( (tmp = readlink(pathtmp,pathtmp,PATH_MAX) ) == -1) {
+
+ /* nothing there? fine, exit */
+ if(errno == ENOENT) {
+ _exit(0);
+ } else if (errno != EINVAL) {
+ perror("readlink");
+ _exit(1);
+ }
+
+ /* restore original name, file is not a link */
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+
+ if(on) {
+ strcat(pathtmp,C_ON);
+ } else {
+ strcat(pathtmp,C_OFF);
+ }
+ tmp = strlen(pathtmp);
+ } else {
+ /* add '\0', readlink forgets it */
+ pathtmp[tmp] = '\0';
+ }
+ tmp++; /* add memory for \0 */
+
+ /********** build argv0 ********/
+ nargv = (char **) malloc( sizeof(char *) );
+ if(nargv == NULL) _exit(1);
+
+ *nargv = (char *) malloc( tmp );
+ if(*nargv == NULL) _exit(1);
+
+ strcpy(*nargv,pathtmp);
+
+ /********************** read params *********************/
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+
+ if(on) {
+ strcat(pathtmp,C_ONARG);
+ } else {
+ strcat(pathtmp,C_OFFARG);
+ }
+
+ /* open params file */
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+
+ if(fd == -1) {
+ perror("open");
+ _exit(1);
+ }
+
+ argc = 0;
+
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX) ) != 0 ) {
+ if(tmp == -1) {
+ perror("read");
+ _exit(1);
+ }
+
+ sbuf = realloc(sbuf,argc + tmp + 1);
+ strncpy(&sbuf[argc],pathtmp,tmp);
+ argc += tmp;
+ }
+ close(fd);
+
+ if(argc)
+ sbuf[argc] = '\0'; /* terminate string */
+
+ } else {
+ sbuf = NULL;
+ }
+
+ /************** build string **************/
+ /* The idea is to reuse the allocated memory. We'll simply
+ * replace the \n with \0 and set a char* to it.
+ * We'll lose the last byte (the initial \0), but we
+ * don't care, as we die some seconds later with execv() */
+
+ argc = 1; /* argv0 */
+ while( sbuf != NULL) {
+ p = strchr(sbuf,'\n');
+ nargv = realloc(nargv, sizeof(char *) * (argc + 1));
+
+ if(nargv == NULL) {
+ LOG("realloc failed");
+ _exit(1);
+ }
+
+ nargv[argc] = sbuf;
+ *p = '\0';
+ if( *(p+1) == '\0') {
+ sbuf = NULL;
+ } else {
+ sbuf = p+1;
+ }
+ argc++;
+ }
+
+ /************ close argv list **************/
+ nargv = realloc(nargv, sizeof(char *) * (argc + 1)); /* 1: NULL-pointer */
+ if(nargv == NULL) {
+ LOG("realloc failed");
+ _exit(1);
+ }
+ nargv[argc] = NULL; /* terminate argv list */
+
+ /********************** read environment *********************/
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,SLASH);
+ if(on) {
+ strcat(pathtmp,C_ONENV);
+ } else {
+ strcat(pathtmp,C_OFFENV);
+ }
+
+ argc = 0;
+ sbuf = NULL;
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+
+ /* if a file exists, failing to open it is an error */
+ if(fd == -1) {
+ perror("open");
+ _exit(1);
+ }
+
+ while ( (tmp = read(fd,pathtmp,PATH_MAX) ) != 0 ) {
+ if(tmp == -1) {
+ perror("read");
+ _exit(1);
+ }
+
+ sbuf = realloc(sbuf,argc + tmp + 1);
+ strncpy(&sbuf[argc],pathtmp,tmp);
+ argc += tmp;
+ }
+ close(fd);
+ if(argc)
+ sbuf[argc] = '\0'; /* terminate string */
+ }
+
+ /************** build environment string **************/
+ argc = 0;
+ while( sbuf != NULL ) {
+ p = strchr(sbuf,'\n');
+
+ nenv = realloc(nenv, sizeof(char *) * (argc + 1));
+ if(nenv == NULL) {
+ LOG("realloc failed");
+ _exit(1);
+ }
+
+ nenv[argc] = sbuf;
+ *p = '\0';
+ if( *(p+1) == '\0') {
+ sbuf = NULL;
+ } else {
+ sbuf = p+1;
+ }
+ argc++;
+ }
+
+ /************ close env list **************/
+ nenv = realloc(nenv, sizeof(char *) * (argc + 1));
+ if(nenv == NULL) {
+ LOG(MSG_ERR_ALLOC);
+ _exit(1);
+ }
+ nenv[argc] = NULL;
+
+ /****************** EXECUTE ********************/
+
+ execve(nargv[0],nargv,nenv);
+
+ /* we should never reach this block */
+ perror(MSG_ERR_EXECVE);
+ _exit(1);
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/kill_svc.c b/software/cinit/browse_source/cinit-0.0.4/client/kill_svc.c
new file mode 100644
index 00000000..d9ce3a8c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/kill_svc.c
@@ -0,0 +1,104 @@
+KOPIE VON RUN_SVC
+
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+/***********************************************************************
+ * run_svc: run a service and beforeo all dependencies
+ */
+void kill_svc(char *rpath, pid_t pid)
+{
+ int tmp;
+ char svc[PATH_MAX], svcparams[PATH_MAX];
+ struct stat buf;
+
+ D_PRINTF("starte kill_svc");
+ D_PRINTF(rpath);
+
+ /******************* absolute PATH ***************/
+ /* get current working dir */
+ if(! (int) getcwd(pathtmp,PATH_MAX)) {
+ perror("getcwd");
+ return 0;
+ }
+
+ /* change to rpath */
+ if(chdir(rpath) == -1) {
+ perror("chdir");
+ return 0;
+ }
+
+ /* get absolute name of rpath */
+ if(! (int) getcwd(abspath,PATH_MAX)) {
+ perror("getcwd2");
+ return 0;
+ }
+
+ /* change back */
+ if(chdir(pathtmp) == -1) {
+ perror("chdir2");
+ return 0;
+ }
+
+ /******************* REGISTER SERVICE ***************/
+ D_PRINTF(abspath);
+ tmp = msg_start_svc(abspath); /* mark us as temporary */
+ if(tmp == -1) return 1; /* already started */
+
+ /******************* BEGIN DEPENDENCIES ***************/
+ D_PRINTF("Starte needs");
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_NEEDS);
+ if( ! run_run_svcs(pathtmp) ) {
+ /* FIXME: add log + service name here */
+ D_PRINTF("some NEEDED services failed)");
+ msg_change_status(abspath, ST_FAIL, 0);
+ return 0;
+ }
+
+ D_PRINTF("Starte wants");
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_WANTS);
+ run_run_svcs(pathtmp); /* don't care about what happens with the want svc */
+
+ /******************* execute services ***************/
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN);
+
+ if( stat(pathtmp,&buf) == 0) {
+ D_PRINTF("Respawning");
+ pid = respawn_svc(abspath);
+ tmp = ST_RESPAWN;
+ } else {
+ D_PRINTF("exec_unce");
+ pid = exec_svc(abspath);
+ tmp = ST_ONCE;
+ }
+
+ if(!pid) {
+ msg_change_status(abspath, ST_FAIL, pid);
+ return 0;
+ }
+
+ D_PRINTF("Melde status");
+ if(!msg_change_status(abspath, tmp, pid) ) {
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/msg_change_status.c b/software/cinit/browse_source/cinit-0.0.4/client/msg_change_status.c
new file mode 100644
index 00000000..837d87b6
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/msg_change_status.c
@@ -0,0 +1,29 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * tell cinit that I want change the status of a service
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+int msg_change_status(char *svc, char status, pid_t pid)
+{
+ D_PRINTF(svc);
+
+ if(!begin_msg(CMD_CHG_STATUS)) return 0;
+
+ if(!do_change_status(svc,&status,&pid,sock,ACT_CLIENT)) {
+ return 0;
+ }
+
+ if(!do_result(sock,NULL)) {
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/msg_start_svc.c b/software/cinit/browse_source/cinit-0.0.4/client/msg_start_svc.c
new file mode 100644
index 00000000..d7e8867c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/msg_start_svc.c
@@ -0,0 +1,26 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * tell cinit that I want to start a service
+ * part of cinit
+ */
+
+#include
+#include
+#include
+
+#include "cinit.h"
+
+int msg_start_svc(char *svc)
+{
+ D_PRINTF(svc);
+
+ D_PRINTF("writing message begin");
+ if(!begin_msg(CMD_START_SVC)) return 0;
+ D_PRINTF("writing service infos");
+ if(!do_start_svc(sock,svc,ACT_CLIENT)) return 0;
+ D_PRINTF("reading result");
+ if(!do_result(sock,NULL)) return 0;
+ D_PRINTF("gutes ende");
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/respawn_svc.c b/software/cinit/browse_source/cinit-0.0.4/client/respawn_svc.c
new file mode 100644
index 00000000..e5c5d4c2
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/respawn_svc.c
@@ -0,0 +1,68 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets (relative or absolute) path */
+pid_t respawn_svc(char *abspath)
+{
+ pid_t pid;
+ int status;
+ int pipefd[2];
+
+ if(pipe(pipefd) == -1) {
+ perror("pope");
+ return 0;
+ }
+
+ pid = fork();
+ if(pid == -1) {
+ perror("forke");
+ return 0;
+ }
+
+ /******************** PARENT ********************/
+ if(pid > 0) {
+ /* if we read anything, our child succeded */
+ if( read(pipefd[0],&status,sizeof(status)) == -1) {
+ perror("read pope");
+ return 0;
+ }
+ return pid; /* return watchers pid */
+ }
+
+ /******************** CHILD ********************/
+ /* FIXME: add signal handler for shut down */
+
+ status = 1;
+ if( write(pipefd[1],&status,sizeof(status)) == -1) {
+ perror("read pope");
+ _exit(1);
+ }
+
+ while( status ) {
+ D_PRINTF(abspath);
+ pid = exec_svc(abspath, status);
+
+ waitpid(pid,&status,0);
+
+ if( ! WIFEXITED(status) ) {
+ if( WEXITSTATUS(status) ) {
+ /* sleep conf/c_sleep seconds on error exit */
+ sleep(SLEEP_SVC);
+ D_PRINTF("schlecht gestorben");
+ }
+ }
+ }
+
+ _exit(0);
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/run_run_svc.c b/software/cinit/browse_source/cinit-0.0.4/client/run_run_svc.c
new file mode 100644
index 00000000..9cea0f33
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/run_run_svc.c
@@ -0,0 +1,77 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run services parallel
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+
+/***********************************************************************
+ * parallel run forked() run_svc()
+ */
+
+int run_run_svcs(char *abspath)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char pathbuf[PATH_MAX];
+ pid_t pids[MAX_DEPS];
+ int status, i=0, ret = 1;
+
+ D_PRINTF(abspath);
+
+ d_tmp = opendir(abspath);
+
+ /* if there is no such dir, we are finished */
+ if(d_tmp == NULL) {
+ return 1;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ /* ignore . and .. and everything with a . at the beginning */
+ if ( *(tdirent->d_name) == '.') continue;
+
+ if(i < MAX_DEPS) {
+ pids[i] = fork();
+ i++;
+ } else {
+ LOG("to many dependencies");
+ break;
+ }
+
+ if(pids[i-1] == -1) { /* err */
+ LOG("fork failed");
+ return 0;
+ }
+
+ if(pids[i-1] == 0) { /* child */
+ strcpy(pathbuf,abspath);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,tdirent->d_name);
+ if ( run_svc(pathbuf) )
+ _exit(0);
+ else
+ _exit(1);
+ }
+ }
+
+ closedir(d_tmp);
+
+ /* wait for pids */
+ while(i >= 0) {
+ waitpid(pids[i], &status, 0);
+
+ if( ! WIFEXITED(status)) {
+ ret = 0;
+ }
+ i--;
+ }
+ return ret;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/client/run_svc.c b/software/cinit/browse_source/cinit-0.0.4/client/run_svc.c
new file mode 100644
index 00000000..9c765cc0
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/client/run_svc.c
@@ -0,0 +1,111 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+/* headers are clean */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+/***********************************************************************
+ * run_svc: run a service and beforeo all dependencies
+ */
+int run_svc(char *rpath)
+{
+ int tmp;
+ pid_t pid;
+ char abspath[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ struct stat buf;
+
+ D_PRINTF("starte run_svc");
+ D_PRINTF(rpath);
+
+ /******************* absolute PATH ***************/
+ /* get current working dir */
+ if(! (int) getcwd(pathtmp,PATH_MAX)) {
+ perror("getcwd");
+ return 0;
+ }
+
+ /* change to rpath */
+ if(chdir(rpath) == -1) {
+ perror("chdir");
+ return 0;
+ }
+
+ /* get absolute name of rpath */
+ if(! (int) getcwd(abspath,PATH_MAX)) {
+ perror("getcwd2");
+ return 0;
+ }
+
+ /* change back */
+ if(chdir(pathtmp) == -1) {
+ perror("chdir2");
+ return 0;
+ }
+
+ /******************* REGISTER SERVICE ***************/
+ D_PRINTF(abspath);
+ tmp = msg_start_svc(abspath); /* mark us as temporary */
+ if(tmp == -1) return 1; /* already started */
+
+ /******************* BEGIN DEPENDENCIES ***************/
+ D_PRINTF("Starte needs");
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_NEEDS);
+
+ if( stat(pathtmp,&buf) == 0 ) {
+ if( ! run_run_svcs(pathtmp) ) {
+ /* FIXME: add log + service name here */
+ D_PRINTF("some NEEDED services failed");
+ msg_change_status(abspath, ST_FAIL, 0);
+ return 0;
+ }
+ }
+
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_WANTS);
+
+ if( stat(pathtmp,&buf) == 0 ) {
+ D_PRINTF("Starte wants");
+ run_run_svcs(pathtmp); /* don't care about what happens with the want svc */
+ }
+
+ /******************* execute services ***************/
+ /*FIXME: check for C_ON, otherwise we are done! */
+
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN);
+
+ if( stat(pathtmp,&buf) == 0) {
+ pid = respawn_svc(abspath);
+ tmp = ST_RESPAWN;
+ } else {
+ tmp = 1;
+ pid = exec_svc(abspath, tmp);
+ tmp = ST_ONCE;
+ }
+
+ D_PRINTF("Melde status");
+ if(!pid) {
+ msg_change_status(abspath, ST_FAIL, pid);
+ return 0;
+ }
+
+ if(!msg_change_status(abspath, tmp, pid) ) {
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/comm/README b/software/cinit/browse_source/cinit-0.0.4/comm/README
new file mode 100644
index 00000000..840c9742
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/comm/README
@@ -0,0 +1,3 @@
+comm/
+ The communication part of cinit.
+ The functions are used in client and in server code.
diff --git a/software/cinit/browse_source/cinit-0.0.4/comm/do_change_status.c b/software/cinit/browse_source/cinit-0.0.4/comm/do_change_status.c
new file mode 100644
index 00000000..5e43654b
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/comm/do_change_status.c
@@ -0,0 +1,69 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * change status of a service
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+/* client:
+ * svc = service name
+ * status = status
+ * pid = pid
+ * sock2 = sock
+ * action = ACT_WRITE
+ * return: error code
+ *
+ * server:
+ * svc = buffer
+ * status = where to save status
+ * svc = bufferTH_MAX
+ * pid = where to save pid
+ * sock2 = nsock
+ * action = ACT_READ
+ * return: read service lenght
+ */
+
+int do_change_status(char *svc, char *status, pid_t *pid, int sock2, int action)
+{
+ int tmp;
+ ssize_t (*fpoint)(int,void* ,size_t);
+
+ if(action == ACT_SERV) {
+ fpoint = read;
+ } else {
+ fpoint = ( ssize_t (*)(int, void*, size_t) ) write;
+ tmp = strlen(svc);
+ }
+
+ if(fpoint(sock2,&tmp,sizeof(tmp)) == -1) { /* length */
+ perror("i/o: length");
+ return 0;
+ }
+
+ if(tmp > PATH_MAX) {
+ return 0;
+ }
+
+ if(fpoint(sock2,svc,tmp) == -1) { /* write service name */
+ perror("i/o: service name");
+ return 0;
+ }
+
+ if(fpoint(sock2,status,sizeof(*status)) == -1) { /* status */
+ perror("i/o: status");
+ return 0;
+ }
+
+ if(fpoint(sock2,pid,sizeof(*pid)) == -1) { /* PID */
+ perror("i/o: PID");
+ return 0;
+ }
+
+ return tmp;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/comm/do_result.c b/software/cinit/browse_source/cinit-0.0.4/comm/do_result.c
new file mode 100644
index 00000000..3bf78718
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/comm/do_result.c
@@ -0,0 +1,32 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * write result of action
+ * part of cinit
+ */
+
+#include
+#include
+#include
+
+#include "cinit.h"
+
+/* one handler for read and write! */
+char do_result(int sock2, char *value)
+{
+ ssize_t (*fpoint)(int,void* ,size_t);
+ char buf;
+
+ if(value == NULL) { /* client */
+ value = &buf;
+ fpoint = read;
+ } else {
+ fpoint = ( ssize_t (*)(int, void*, size_t) ) write;
+ }
+
+ if(fpoint(sock2,value,1) == -1) { /* result */
+ perror("i/o: result");
+ return 0;
+ }
+
+ return *value;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/comm/do_start_svc.c b/software/cinit/browse_source/cinit-0.0.4/comm/do_start_svc.c
new file mode 100644
index 00000000..959a0001
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/comm/do_start_svc.c
@@ -0,0 +1,49 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * try to start a service
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include "cinit.h"
+
+/* serv:
+ * get buf
+ * return length
+ *
+ * client:
+ * print svc
+ * return errorcode
+ */
+int do_start_svc(int sock2, char *svc, int action)
+{
+ int tmp;
+ ssize_t (*fpoint)(int,void* ,size_t);
+
+ /* set pointers */
+ if(action == ACT_CLIENT) {
+ fpoint = ( ssize_t (*)(int, void*, size_t) ) write;
+ tmp = strlen(svc);
+ } else {
+ fpoint = read;
+ }
+
+ /* read / write lenght */
+ if( fpoint(sock2,&tmp,sizeof(tmp)) == -1) {
+ perror("i/o: len");
+ return 0;
+ }
+
+ if(tmp > PATH_MAX) return 0;
+
+ /* write/read service name */
+ if( fpoint(sock2,svc,tmp) == -1) {
+ perror("i/o: service name");
+ return 0;
+ }
+
+ return tmp;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/.README b/software/cinit/browse_source/cinit-0.0.4/conf/.README
new file mode 100644
index 00000000..5d4a5a00
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/.README
@@ -0,0 +1 @@
+This directory contains the cinit configuration.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_env b/software/cinit/browse_source/cinit-0.0.4/conf/c_env
new file mode 100644
index 00000000..ec4d643b
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_env
@@ -0,0 +1,9 @@
+.env
+
+The extension to c_on and c_off, which will contain the environment \n seperated.
+
+For instance:
+
+CLIENT_IP=192.168.23.42
+ACCEPT_CONN=32
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_halt b/software/cinit/browse_source/cinit-0.0.4/conf/c_halt
new file mode 100644
index 00000000..bc062a2c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_halt
@@ -0,0 +1,4 @@
+halt
+
+Name of the service we should start when 'halting' (system stop, but no
+power off).
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_init b/software/cinit/browse_source/cinit-0.0.4/conf/c_init
new file mode 100644
index 00000000..22a77d8e
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_init
@@ -0,0 +1,3 @@
+init
+
+The name of the init service.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_needs b/software/cinit/browse_source/cinit-0.0.4/conf/c_needs
new file mode 100644
index 00000000..eb715d7d
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_needs
@@ -0,0 +1,3 @@
+needs
+
+Name of the service sub-directory containing the needed services.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_off b/software/cinit/browse_source/cinit-0.0.4/conf/c_off
new file mode 100644
index 00000000..57e63cea
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_off
@@ -0,0 +1,3 @@
+off
+
+Name of the file we start, when stopping the service.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_on b/software/cinit/browse_source/cinit-0.0.4/conf/c_on
new file mode 100644
index 00000000..8eadc0a5
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_on
@@ -0,0 +1,3 @@
+on
+
+Name of the file we start, when starting the service.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_params b/software/cinit/browse_source/cinit-0.0.4/conf/c_params
new file mode 100644
index 00000000..d86d37cb
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_params
@@ -0,0 +1,3 @@
+.params
+
+The extension to c_on and c_off, which will contain the parameters \n seperated.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_poweroff b/software/cinit/browse_source/cinit-0.0.4/conf/c_poweroff
new file mode 100644
index 00000000..273d4bec
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_poweroff
@@ -0,0 +1,3 @@
+poweroff
+
+Name of the service we should start, when system power-off is called.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_reboot b/software/cinit/browse_source/cinit-0.0.4/conf/c_reboot
new file mode 100644
index 00000000..17937b4a
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_reboot
@@ -0,0 +1,3 @@
+reboot
+
+Name of the service we should start on reboot.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_respawn b/software/cinit/browse_source/cinit-0.0.4/conf/c_respawn
new file mode 100644
index 00000000..cc85fbea
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_respawn
@@ -0,0 +1,3 @@
+respawn
+
+If this file exists in a service directory, cinit will respawn the service.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_sock b/software/cinit/browse_source/cinit-0.0.4/conf/c_sock
new file mode 100644
index 00000000..46a50941
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_sock
@@ -0,0 +1,4 @@
+coala
+
+The name of the socket cinit will use (currently: below tmpdir,
+see doc/ipc.thoughts).
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_tmp b/software/cinit/browse_source/cinit-0.0.4/conf/c_tmp
new file mode 100644
index 00000000..48e98e42
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_tmp
@@ -0,0 +1,3 @@
+tmp
+
+The name of the temporary directory, where we'll mount tmpfs to create the socket
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_tmpfs b/software/cinit/browse_source/cinit-0.0.4/conf/c_tmpfs
new file mode 100644
index 00000000..ba29caef
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_tmpfs
@@ -0,0 +1,4 @@
+tmpfs
+
+The name of the filesystem to use to mount a memory filesystem.
+On Linux this is "tmpfs".
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_tmpmount b/software/cinit/browse_source/cinit-0.0.4/conf/c_tmpmount
new file mode 100644
index 00000000..3469fe57
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_tmpmount
@@ -0,0 +1,4 @@
+tmpfs
+
+The name of the mount target, we'll mount with c_tmpfs on the c_tmp directory.
+On Linux this can be anything, but we will use the default "tmpfs".
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/c_wants b/software/cinit/browse_source/cinit-0.0.4/conf/c_wants
new file mode 100644
index 00000000..20fe3184
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/c_wants
@@ -0,0 +1,3 @@
+wants
+
+Name of the service sub-directory containing the wanted services.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/cinit_dir b/software/cinit/browse_source/cinit-0.0.4/conf/cinit_dir
new file mode 100644
index 00000000..06e7d1ff
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/cinit_dir
@@ -0,0 +1,3 @@
+/etc/cinit
+
+This is where all configuration for cinit will be stored.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/destdir b/software/cinit/browse_source/cinit-0.0.4/conf/destdir
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/destdir
@@ -0,0 +1 @@
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/getty_dir b/software/cinit/browse_source/cinit-0.0.4/conf/getty_dir
new file mode 100644
index 00000000..75d31cb2
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/getty_dir
@@ -0,0 +1,4 @@
+getty
+
+This is the subdirectry in which the scripts will create the gettys,
+if you are using 'install-example'. It's not used be cinit internally.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/install_directory b/software/cinit/browse_source/cinit-0.0.4/conf/install_directory
new file mode 100644
index 00000000..c8d9e45b
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/install_directory
@@ -0,0 +1,3 @@
+-d
+
+Parameter to install_prog to create directories.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/install_prog b/software/cinit/browse_source/cinit-0.0.4/conf/install_prog
new file mode 100644
index 00000000..2f21943a
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/install_prog
@@ -0,0 +1,4 @@
+/usr/bin/install
+
+Program we use to install. install_directory contains parameter
+to create directory.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/prefix b/software/cinit/browse_source/cinit-0.0.4/conf/prefix
new file mode 100644
index 00000000..580ae0cb
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/prefix
@@ -0,0 +1,4 @@
+/
+
+Where to install cinit. Normally this will be /, but you can put in anywhere.
+The subdirectory 'sbin' under this prefix must be reabable by the kernel.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/sleep_kill b/software/cinit/browse_source/cinit-0.0.4/conf/sleep_kill
new file mode 100644
index 00000000..de1fd006
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/sleep_kill
@@ -0,0 +1,5 @@
+2
+
+Seconds to sleep after sending SIGTERM, before sending SIGKILL to every
+process. 5 is a good working value, but makes me tired. Testing with
+2 currently.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/sleep_svc b/software/cinit/browse_source/cinit-0.0.4/conf/sleep_svc
new file mode 100644
index 00000000..e20aed6a
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/sleep_svc
@@ -0,0 +1,3 @@
+5
+
+How many seconds to sleep before respawning a failed process.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/sock_group b/software/cinit/browse_source/cinit-0.0.4/conf/sock_group
new file mode 100644
index 00000000..d4c1adda
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/sock_group
@@ -0,0 +1,3 @@
+root
+
+The group, which should own the communication socket.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/sock_mode b/software/cinit/browse_source/cinit-0.0.4/conf/sock_mode
new file mode 100644
index 00000000..b2a727b0
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/sock_mode
@@ -0,0 +1,3 @@
+0770
+
+Octal mode of socket.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/sock_queue b/software/cinit/browse_source/cinit-0.0.4/conf/sock_queue
new file mode 100644
index 00000000..4917a1f8
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/sock_queue
@@ -0,0 +1,4 @@
+32
+
+Maximum process waiting in the socket queue. The default is much
+more than enough.
diff --git a/software/cinit/browse_source/cinit-0.0.4/conf/sock_user b/software/cinit/browse_source/cinit-0.0.4/conf/sock_user
new file mode 100644
index 00000000..34274f4f
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/conf/sock_user
@@ -0,0 +1,3 @@
+root
+
+The one who should own the communication socket.
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/.buildwarn b/software/cinit/browse_source/cinit-0.0.4/doc/.buildwarn
new file mode 100644
index 00000000..43c26832
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/.buildwarn
@@ -0,0 +1,20 @@
+
+-------------
+W A R N I N G
+-------------
+
+****************************************************************************
+THIS IS A PRE-RELEASE, NOT YET THOUGHT TO BE USED IN PRODUCTIVE ENVIRONMENT!
+****************************************************************************
+
+First of all configure cinit through the configuration files found in conf/.
+Especially look at conf/*tmp*.
+
+The documentation can be found in doc/.
+
+After reading and configuring use:
+
+ "make all" - to build cinit
+ "make install" - to install cinit
+ "make install-example" - to install cinit configuration example
+ -> WARNING: the last two make targets do not honour $DESTDIR yet!
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/caveats b/software/cinit/browse_source/cinit-0.0.4/doc/caveats
new file mode 100644
index 00000000..3eac4a92
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/caveats
@@ -0,0 +1,14 @@
+'Geheimnisse' in German
+
+
+- Dependencies beginning with a '.' (dot) are ignored.
+ So you can temporary disable a dependency moving it to
+ want/.name
+
+- Why is the name of the socket "coala"?
+ Well, coala could mean 'cinit object abstract layer access', but
+ perhaps it's a much simpler reason.
+
+- cinit will start a little bit faster, if you omit non needed
+ 'wants' and 'needs' dirs, as they need to be scanned, if they
+ exist
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/cinit.commands b/software/cinit/browse_source/cinit-0.0.4/doc/cinit.commands
new file mode 100644
index 00000000..3614b3c7
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/cinit.commands
@@ -0,0 +1,89 @@
+--------------------------------------------------------------------------------
+cinit commands, Nico Schottelius 2005-04-28
+--------------------------------------------------------------------------------
+
+cinit allows communication through a socket (see ipc.thoughs for reasons).
+
+Sockets allow to find out the accessing uid, gid and pid (uses SO_PEERCRED as
+socketoption).
+
+The communication-protocol is binary.
+
+--------------------------------------------------------------------------------
+Protocol overview
+--------------------------------------------------------------------------------
+
+Any communication begins with a command. A command is a one byte
+unsigned char. Depending on the command, the communication has its own
+semantics.
+
+
+Commands are: (values can be found in cinit.h)
+
+ CMD_START_SVC: I want to start a service.
+ CMD_CHG_STATUS: I want to change the status of a service.
+ CMD_STOP_SVC: Please shutdown a service and its dependencies.
+ CMD_KILL_SVC: Shutdown a service, don't care about its dependencies.
+
+ CMD_RESCUE: Kill everything, and spawn a sulogin shell.
+ CMD_INIT: Start all services (again possibly).
+
+ CMD_HALT: Halt the system*)
+ CMD_REBOOT: Reboot the system*)
+ CMD_POWEROFF: Power-off the system*)
+
+ *) The commands are not and maybe will never be implemented,
+ as they are realized as signals.
+
+--------------------------------------------------------------------------------
+Detailled command-listing
+--------------------------------------------------------------------------------
+
+CMD_START_SVC
+ 1. int len; /* length of service name, including \0 */
+ 2. char *svc; /* name of the service, absolute pathname */
+
+ cinit returns:
+ a) ok, a SID, a service ID: int svc_id; [ really need int? ]
+ b) fail, [currently only fail is returned]
+ a) already running
+ b) svc_name too long / not allowed
+
+ [ A service identification is used for faster searching in cinit.
+ It is also a hint for developers of external software, that they should not
+ be able to use CMD_CHG_STATUS, if they didn't start a service.
+ They should use CMD_STOP_SVC to stop a service.
+ Starting a service is currently done via exec() in the external program or
+ a cinit-fork(). ]
+
+CMD1CHG_STATUS: I want to change the status of a service.
+ 0. int len;
+ 1. char *svc;
+ 2. char status; /* status:
+ once: started successfully the service once.
+ fail: tried to start once, but the service exit ungracefully
+ respawn: I am on it, as soon it exists I'll restart! */
+ 2. pid_t pid /* the pid of the service, if started once
+ or the pid of the service watcher, if respawning */
+
+ cinit returns: MSG_OK|MSG_FAIL (char)
+
+CMD_STOP_SVC: Please shutdown a service and its dependencies.
+ 1. int len; /* length of service name, including \0 */
+ 2. char *svc; /* name of the service, absolute pathname */
+
+ cinit returns: ready...
+
+CMD_KILL_SVC: Shutdown a service, don't care about its dependencies.
+ 1. int len; /* length of service name, including \0 */
+ 2. char *svc; /* name of the service, absolute pathname */
+
+ cinit returns: ready...
+
+CMD_INIT: Start all services (again possibly).
+ cinit returns: ready...
+
+CMD_RESCUE: Kill everything, and spawn a sulogin shell.
+CMD_HALT: Halt the system.
+CMD_REBOOT: Reboot the system.
+CMD_POWEROFF: Power-off the system.
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/configuring.cinit b/software/cinit/browse_source/cinit-0.0.4/doc/configuring.cinit
new file mode 100644
index 00000000..61880098
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/configuring.cinit
@@ -0,0 +1,12 @@
+--------------------------------------------------------------------------------
+configuring cinit, Nico Schottelius 2005-05-28
+--------------------------------------------------------------------------------
+
+Services
+mostly no shell scripts
+linking to system configuration
+adding services with cinit.add.service? -> later, meta-deps?
+pidfilehack - from fefe/minit?
+
+meta-deps
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/fun/testing01 b/software/cinit/browse_source/cinit-0.0.4/doc/fun/testing01
new file mode 100644
index 00000000..47e4b74d
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/fun/testing01
@@ -0,0 +1,20 @@
+kind tot 17 ...
+Read path: /
+Read path: e
+Read path: t
+Read path: c
+Read path: /
+Read path: c
+Read path: i
+Read path: n
+Read path: i
+Read path: t
+Read path: /
+Read path: t
+Read path: e
+Read path: s
+Read path: t
+Read path: s
+Read path: v
+Read path: c
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/how_it_works_internally b/software/cinit/browse_source/cinit-0.0.4/doc/how_it_works_internally
new file mode 100644
index 00000000..9c836cb0
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/how_it_works_internally
@@ -0,0 +1,26 @@
+The following is a very simple process structure of cinit internals:
+
+cinit-main starts
+\
+ |-> execute run_init_svc()
+ | \ run_svc(CINIT_INIT);
+ | | check status <-------------------\
+ | | set status = temp |
+ | \ check dependencies |
+ | | fork(run_svc()) for every WANT |
+ | | run_svc() for every NEED /
+ | / check if respawning { do .. while(repawn?)
+ | \ yes: (remember: run_svc _must_ return!)
+ | | msg_change_status(respawn)
+ | | add watcher_signal handler to stop! (SIGTERM)
+ | | fork(exec_svc) <--|
+ | | waitpid(fork) | while(1) { ... }
+ | \ sleep(WAIT_SECS) ---/
+ | | no: fork(exec_svc)
+ | \ waitpid(fork) -> yes, wait!
+ | | msg_change_status
+ | /
+ | /
+ | -> while(1)
+ | - listen to signals
+ | - listen on socket
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/ipc.thoughts b/software/cinit/browse_source/cinit-0.0.4/doc/ipc.thoughts
new file mode 100644
index 00000000..d7352559
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/ipc.thoughts
@@ -0,0 +1,74 @@
+--------------------------------------------------------------------------------
+Thoughts about different UNIX-IPC, Nico Schottelius 2005-04-28
+--------------------------------------------------------------------------------
+
+Howto cinit communicates with
+ a) cinit-forks
+ b) any other program
+
+a) cinit-forks
+
+a.1) shared memory
+
+Access could generally be done with shared memory. The problem with
+that is, that -lrt is required, which implicits -lpthread, which
+makes linking staticly problematic (at least for glibc).
+
+a.2) pipes
+
+A maximum of ~510 pipes could be used ( (1024-3)/2),
+1024=max fds, -3=already opened (stderr/stdin/stdout), /2=
+two fds needed per clients).
+
+Pipes cannot be use easily through forks of forks.
+
+a.3) fifos
+
+FIFOs are easy to use, but you would need to create two FIFOs
+for _every_ service, as with only two FIFOs we cannot reliable
+detect, _who_ is writting to us currently and who wants to read.
+
+a.4) system-v-ipc
+
+No documentation found nor tested.
+
+a.5) sockets
+
+Are indeed a very clean way. There's only one problem:
+bind() fails on read-only mounted devices:
+
+ - The socket either does not exists and cannot be created
+ - or the socket exists, but bind() refuses to reuse it
+ (error: Address already in use)
+
+Imho bind() should even honour the socket-option SO_REUSEADDR,
+which allows to re-use a socket, if there's no other program bound to.
+
+As far as I can see, SO_REUSEADDR is only honoured, if socket is of
+type PF_INET (we use PF_UNIX) and POSIX does only specify how to
+check for support, but not that sockets have to be able to use
+SO_REUSEADDR.
+
+That way, we are forced to mount a temporary filesystem on
+/etc/cinit/tmp and create the socket below this directory. This is not
+the clean and easy solution one would wish. Still, sockets
+seem to be the cleanest and most reliable way to have IPC for
+this situation.
+
+See socket(2), bind(2), listen(2), accept(2), socket(7) and unix(7)
+for help.
+
+b) any other program
+
+What you can do is to tell cinit to
+ - reboot,
+ - halt and
+ - poweroff.
+
+Simple send cinit a signal, what todo:
+ SIGUSR1: reboot
+ SIGUSR2: poweroff
+ TERM: halt
+
+See signal(2) and signal(7) for help and serv/sig_reboot.c for implementation.
+--------------------------------------------------------------------------------
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/ipc.usenet.posting b/software/cinit/browse_source/cinit-0.0.4/doc/ipc.usenet.posting
new file mode 100644
index 00000000..28abcec3
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/ipc.usenet.posting
@@ -0,0 +1,48 @@
+From: Nico Schottelius
+Subject: Unix IPC, socket/AF_UNIX; bind on r/o devices?
+Date: 09 May 2005 09:51:27 GMT
+To: comp.unix.programmer
+
+Hello!
+
+Situation:
+ - everything mounted readonly (as when starting the system)
+ - one process with n children, which may have n children (recursive)
+ - all the children and children of children should be able to talk to the
+ first parent
+
+Problem:
+ - Using bind() will fail, because
+ a) socket cannot created
+ b) the existing socket cannot be reused
+
+Other possibilities not working:
+ - shared memory is not an option, as one need
+ -lrt, which needs -lpthread, which is problematic to link statically
+
+ - pipes: handling the pipes from parent to child of child of child
+ would be hard to program
+
+ - socketpair: should be the same problematic as it's with pipes
+
+ - fifos: one would have to create the fifos before and two fifos
+ for each child; possible, but very unelegant; and one would have
+ to memorize, which child is connected to which fifo; again possible,
+ but somehow unelegant
+
+ - signaling: one could implement communication with some kind of
+ morse code with signals, but that won't be a good solution
+
+Questions:
+ - Is there any way, case b) (socket already existing) can be solved in
+ a way that I tell bind() to use an existing socket?
+ - What would be the best solution to talk bidirectional to clients
+ in this scenario?
+
+I appreciate any hint, as I really like the socket mechanism and would
+like to keep it.
+
+
+Thanks in advance,
+
+Nico
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/meta.dependencies b/software/cinit/browse_source/cinit-0.0.4/doc/meta.dependencies
new file mode 100644
index 00000000..02f05bef
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/meta.dependencies
@@ -0,0 +1,55 @@
+--------------------------------------------------------------------------------
+Meta-dependencies,
+Nico Schottelius 2005-05-24
+--------------------------------------------------------------------------------
+
+1. What are Meta-Dependencies?
+2. What are the advantages / disadvantages of it?
+3. The solutions
+
+1. What are Meta-Dependencies?
+
+A Meta-depedency describes the type of service another service wants, but
+not the exact service.
+
+Example:
+ remote-services/ssh wants a dns-resolver, it does not care about
+ what it is (tinycach, bind, maradns, ...), but that it does
+ name caching.
+
+
+2. What are the advantages / disadvantages of it?
+
+Meta means beeing indirect. Indirect means beeing slow. So, if
+cinit would have to care about meta-dependencies, the code would become
+much bigger, bloatig and much slower.
+
+On the other hand, on would perhaps like to use meta-dependencies, if
+one tests different services with the same functionality or switches
+them dependending on the situation.
+
+
+3. The solutions
+
+As told above, cinit won't care about meta-dependencies and as you'll see
+it does not need to.
+
+The first solution would be to have a mapping table outside of cinit.
+This table could be a file for every meta-dependency and contain the
+possibilities:
+
+ dns-resolver:
+ remote-services/bind
+ local-services/tinydns
+ ...
+
+So one would have to call a program, which creates the real cinit
+configuration. This is imho not a very elegant solution and could cause
+problems, when handling self-written services.
+
+Another possibility is to use symlinks: Create service-directories
+for all services beeing installed, but do dependencies in "wants/"
+and "needs/" to a symlink (for instance create /etc/cinit/meta
+and link to real services in there):
+
+ /etc/cinit/meta/dns-resolver -> ../remote-services/bind/
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/posix.aardvark.bug.report b/software/cinit/browse_source/cinit-0.0.4/doc/posix.aardvark.bug.report
new file mode 100644
index 00000000..0c606b41
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/posix.aardvark.bug.report
@@ -0,0 +1,52 @@
+To: austin-review-l__AT__opengroup.org
+From: nico-posix__AT__schottelius.org
+Subject: Bug in TC2-d6 bind - bind a name to a socket
+Reply-To: austin-group-l__AT__opengroup.org
+
+ Bug report from : Nico Schottelius , cLinux
+
+(Note that the reply-to line automatically redirects
+to austin-group-l__AT__opengroup.org for further discussion on bug reports)
+
+@ page 1 line 0 section bind - bind a name to a socket objection {-1}
+
+Problem:
+
+bind should 'assign a name to a socket', but in particular environments it will fail, where it could succeed.
+
+Long Description:
+
+When opening a new socket, with type PF_UNIX
+(sock = socket(PF_UNIX,SOCK_STREAM,0);) and one sets
+the socket option SO_REUSEADDR
+(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp))),
+bind does not honour this setting.
+
+It is reported on irc channels, that SO_REUSEADDR is only supported on
+PF_INET sockets and that's what I would claim a bug.
+
+If a socket exists in the filesystem and no process is bound to
+it, bind wail fail anyway.
+
+This is especially problematic, when one is in an environment,
+which is pre-startup (like beeing init) and one wants to use
+sockets, but everything is mounted read-only.
+
+So, if bind() would honour the option, it would be able
+to bind() to a socket, which exists (as creating one on a
+read-only filesystem is not possible).
+
+
+
+Action:
+
+Proposal:
+
+Add better specification to either socket(7) or bind(2), which
+explains the behaviour of bind, when this option is set
+or even better: Specify, that bind should take care of this bit,
+also when using PF_UNIX.
+
+In general the socket(7) manpage should explain more in detail
+or at least reference other documents (unix(7)?), which explain what the
+option for a specific protocol does.
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/shutting.down b/software/cinit/browse_source/cinit-0.0.4/doc/shutting.down
new file mode 100644
index 00000000..d5b0b2f7
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/shutting.down
@@ -0,0 +1,60 @@
+--------------------------------------------------------------------------------
+Shutting down the system
+Nico Schotteilus, 2005-05-24
+--------------------------------------------------------------------------------
+
+cinit wird normalerweise alles herunterfahren und $etwas tun.
+
+1. What to do to allow a system to shutdown?
+
+Create /etc/cinit/reboot, /etc/cinit/power-off and /etc/cinit/halt.
+
+It's in most scenarios also enough to create only one of those
+service directories and link all others against the first one:
+
+[21:38] ei:cinit# mkdir /etc/cinit/power-off
+[21:38] ei:cinit# ln -s power-off /etc/cinit/reboot
+[21:38] ei:cinit# ln -s power-off /etc/cinit/halt
+
+Then create the needed services, which are almost always:
+
+ - swapoff: disable swap
+ - sync: sync buffers to disk
+ - umount: umount everything
+ - remount: remount root read-only
+
+
+on oder off?????
+
+Add dependencies to
+
+You can also use
+What todo when shutting down (reboot, halt, poweroff) the system:
+
+1. Cycle through service list and
+while(processes--) {
+ Stop_current_processs
+}
+
+ - Stop_current_processs
+ \ if(status = respawn)
+ | -> kill -TERM pid
+ | exec_svc(svc/off, svc/off.params)
+
+kill remaining processes with SIGTERM
+sleep(WAIT_KILL)
+kill remaining processes with SIGKILL
+sync;
+umount(*)
+
+reboot
+
+
+- cycle through running services, kill them the other way round
+- stop respawing processes
+
+- start off-process of running services
+- don't shutdown failed services
+
+kill_svc(struct stat svc);
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/thoughts.closed b/software/cinit/browse_source/cinit-0.0.4/doc/thoughts.closed
new file mode 100644
index 00000000..1da4bebe
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/thoughts.closed
@@ -0,0 +1,24 @@
+1. using SIDs (service IDs) to communicated with external processes
+
+ This was a very bad idea: The external program could exploit us by
+ specifying an arbitary big SID (as the SID is simply the index
+ of our service array).
+
+2. using function pointers to handle messages
+
+ Seems like it works fine. We have handlers for each
+ message (do_*), which are called by client and server.
+ The function pointer is simply to read or write, dependending
+ if it is the client or the server. This way we don't need
+ to rewrite communications parts.
+
+3. Using different storage
+
+ First all services were saved in a service array of the size
+ MAX_SVC. This has been replaced by a double-linked list.
+ Have a look at serv/list.c.
+
+4. Using sockets for IPC (between cinit forks)
+
+ Works very fine, though we have to mount a temporary fs before.
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/doc/thoughts.open b/software/cinit/browse_source/cinit-0.0.4/doc/thoughts.open
new file mode 100644
index 00000000..5e0a054c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/doc/thoughts.open
@@ -0,0 +1,14 @@
+- Using a directory params with 1,2,3,4 for argv
+
+ This would make substituting a single argument easier, but only
+ if you know which one you have to change. This would add
+ an additional dirent(), which would not replace the current read(), but
+ add more open() and close()s.
+
+- Using TCP/IP sockets
+
+ This would be a very small change in the code, but would allow
+ to control cinit over network. Since there is no authentication,
+ this would be highly insecure. On the other hand, cinit
+ could control the parallel start of many hosts, if they
+ should become 'one' computer at the end.
diff --git a/software/cinit/browse_source/cinit-0.0.4/generic/mini_printf.c b/software/cinit/browse_source/cinit-0.0.4/generic/mini_printf.c
new file mode 100644
index 00000000..d384e717
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/generic/mini_printf.c
@@ -0,0 +1,20 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * print string
+ */
+
+#include
+
+void mini_printf(char *str,int fd)
+{
+ char *p;
+
+ p = str;
+ while ( *p != '\0') {
+ write(fd,p,1);
+ p++;
+ }
+
+ write(fd,"\n",1); /* FIXME: only when console */
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/generic/set_signals.c b/software/cinit/browse_source/cinit-0.0.4/generic/set_signals.c
new file mode 100644
index 00000000..aa3233b6
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/generic/set_signals.c
@@ -0,0 +1,45 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux/cinit
+ */
+
+#include
+#include
+#include "cinit.h"
+
+void set_signals(int action)
+{
+ struct sigaction sa;
+
+ if(action == ACT_SERV) {
+ sa.sa_handler=SIG_IGN;
+ } else {
+ sa.sa_handler=SIG_DFL;
+ }
+ sigaction(SIGINT,&sa,NULL); /* ignore ctr+c */
+ sigaction(SIGPIPE,&sa,NULL); /* what todo when pipe/fifo closed */
+ sigaction(SIGCHLD,&sa,NULL); /* what todo when child exited */
+ sigaction(SIGUSR2,&sa,NULL); /* USR2 */
+ sigaction(SIGQUIT,&sa,NULL); /* QUIT... */
+ sigaction(SIGTTIN,&sa,NULL);
+ sigaction(SIGTTOU,&sa,NULL);
+
+ /* sigio is called to act on the socket */
+ if(action == ACT_SERV) {
+ sa.sa_handler=sigio;
+ }
+ sigaction(SIGIO,&sa,NULL);
+
+ /* signal handlers to do special things with: reboot */
+ if(action == ACT_SERV) {
+ sa.sa_handler=sig_reboot;
+ }
+// sigaction(SIGINT,&sa,NULL); /* FIXME: Testing only: ctr+c = REBOOT!!! */
+ sigaction(SIGUSR1,&sa,NULL);
+ sigaction(SIGTERM,&sa,NULL);
+ sigaction(SIGHUP,&sa,NULL);
+
+ /* sigstop can't be ignored, do the manpages say */
+ /* sigaction(SIGSTOP,&sa,NULL); */
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/add_mod_svc.c b/software/cinit/browse_source/cinit-0.0.4/old/add_mod_svc.c
new file mode 100644
index 00000000..c74778d4
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/add_mod_svc.c
@@ -0,0 +1,42 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * add_svc
+ * part of cinit
+ */
+
+#include
+
+#include "cinit.h"
+
+/* we return the service id or -1 on error*/
+int add_mod_svc(char *svc, char status, pid_t pid)
+{
+ int tmp = 0;
+
+ /* check if service exists, if so, set new status, return sid */
+ tmp = chk_svc(svc);
+ if( tmp != -1 ) {
+ svc_list.svca[tmp].status = status;
+ return tmp;
+ }
+
+ /* still here? than there is no such service */
+ if(svc_list.process < MAX_SVC) {
+ printf("[%d]: %s (%d)\n",svc_list.process,svc,pid);
+ svc_list.svca[svc_list.process].abs_path = strdup(svc);
+
+ if(svc_list.svca[svc_list.process].abs_path == NULL) {
+ LOG("strdup failed!");
+ return -1;
+ }
+ svc_list.svca[svc_list.process].pid = pid;
+ /* inkrement later, as we count argv[0..n] */
+ (svc_list.process)++;
+ } else {
+ LOG("too many services");
+ return -1;
+ }
+
+ /* return _our_ service id */
+ return (svc_list.process -1);
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cerr.c b/software/cinit/browse_source/cinit-0.0.4/old/cerr.c
new file mode 100644
index 00000000..b9dec472
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cerr.c
@@ -0,0 +1,36 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * print error to stderr and exist
+ */
+
+#include
+#include "cinit.h"
+
+void cerr(char *string, int status)
+{
+ char *p;
+
+ p = string;
+ while ( *p != '\0') {
+ write(2,p,1);
+ p++;
+ }
+ write(2,"\n",1);
+
+ switch(status) {
+ case RT_CHLD_FAIL:
+ case RT_CHLD_OK:
+ _exit(status);
+ ;;
+ case RT_PAR_FAIL: /* FIXME: if status is RT_PAR_FAIL, start sulogin */
+ _exit(23);
+ ;;
+ case RT_PAR_OK:
+ return;
+ ;;
+ }
+
+/* FIXME: return if in cinit, _exit on fork() */
+// if(...)
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.add.shutdown.reboot.poweroff b/software/cinit/browse_source/cinit-0.0.4/old/cinit.add.shutdown.reboot.poweroff
new file mode 100644
index 00000000..23cae705
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.add.shutdown.reboot.poweroff
@@ -0,0 +1,15 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: add shutdown/reboot/poweroff service
+
+set -e
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+
+# create halt, link reboot and poweroff to it
+mkdir "$BASEDIR/$C_HALT"
+ln -s "$C_HALT" "$BASEDIR/$C_REBOOT"
+ln -s "$C_HALT" "$BASEDIR/$C_POWEROFF"
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.c01 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c01
new file mode 100644
index 00000000..e3890013
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c01
@@ -0,0 +1,105 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux
+ */
+
+#define CINIT_DIR "/etc/cinit"
+
+#define C_INIT "init"
+#define C_SHD "shutdown"
+#define C_REBOOT "reboot"
+
+#define C_NEEDS "needs"
+#define C_WANTS "wants"
+
+/* opendir() */
+#include
+#include
+
+/* *stat() */
+#include
+#include
+
+
+#include
+
+#define EKEL "/etc/cinit/init/wants"
+
+void cerr(char *msg)
+{
+ printf("%s\n", msg);
+}
+
+/*
+ * run_svc: gets a wants/needs directory
+ * returns whether _one_ service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+
+ /* check if already running / ran / currently starting */
+
+ /* check for needs -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es, %s\n", pathbuf);
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) printf("dir gibt es, %s\n", pathbuf);
+
+ d_tmp = opendir(path);
+
+ if(d_tmp == NULL) {
+ cerr("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
+
+int main()
+{
+
+ char buf[256];
+ int tmp;
+
+ strcpy(buf,CINIT_DIR);
+ tmp = strlen(CINIT_DIR);
+ buf[tmp] = '/';
+ strcpy(&buf[tmp+1],C_INIT);
+
+ printf("path: %s\n",buf);
+
+ run_svc("/etc/cinit/init");
+
+ run_svc("/etc/cinit2/init");
+
+ run_svc("/NOT_THERE");
+
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.c02 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c02
new file mode 100644
index 00000000..7e5432b4
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c02
@@ -0,0 +1,198 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux
+ */
+
+#define CINIT_DIR "/etc/cinit"
+
+#define C_INIT "init"
+#define C_SHD "shutdown"
+#define C_REBOOT "reboot"
+
+#define C_NEEDS "needs"
+#define C_WANTS "wants"
+#define C_RUN "run"
+
+/* opendir() */
+#include
+#include
+
+/* *stat() */
+#include
+#include
+
+/* wait() */
+#include
+
+/* strlen */
+#include
+
+#include
+
+#define EKEL "/etc/cinit/init/wants"
+
+void cerr(char *msg)
+{
+ printf("%s\n", msg);
+}
+
+/***********************************************************************
+ * parallel run forked() run_svc()
+ */
+#define MAX_PAR 32
+
+int run_run_svcs(char *rpath)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ pid_t pids[MAX_PAR];
+ int tmp,i=0;
+
+ printf("run_run_svcs on: %s\n",rpath);
+
+ d_tmp = opendir(rpath);
+
+ if(d_tmp == NULL) {
+ printf("Failed to open dir: %s", rpath);
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0
+ || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ if(i < MAX_PAR) {
+ pids[i] = fork();
+ i++;
+ } else {
+ cerr("to many dependencies");
+ return 1;
+ }
+
+ if(pids[i-1] == -1) { /* err */
+ cerr("fork failed\n");
+ return 0;
+ } else if(pids[i-1] == 0) { /* child */
+ printf("Service zu starten nun: %s\n", tdirent->d_name);
+ run_svc(tdirent->d_name);
+ _exit(0);
+ } else /* the parent simply goes the loop again */
+ printf("run_svcs_PARENT\n");
+ }
+
+ closedir(d_tmp);
+
+ /* wait for pids */
+ while(i >= 0) {
+// printf("waiting for %d ... \n",i);
+ waitpid(pids[i], &tmp, 0);
+ i--;
+ }
+}
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether _one_ service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+ /* check if already running / ran / currently starting */
+
+ /* check for service dir */
+ if( stat(path,&buf) ) {
+ printf("no such service: %s\n", path);
+ return 1;
+ }
+
+ /* check for needs -> forked() */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathbuf);
+ tmp = fork();
+ if(tmp == -1) {
+ printf("error ...\n");
+ exit(1);
+ } else if(tmp == 0) { /* child */
+ printf("child for run_run_svcs()\n");
+ run_run_svcs(pathbuf);
+ _exit(0);
+ printf("ZOOOMBIE\n");
+ }
+ else
+ printf("parent\n");
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathbuf);
+ run_run_svcs(pathbuf);
+ }
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ cerr("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
+
+/***********************************************************************
+ * the main procedure
+ */
+
+int main()
+{
+
+ char buf[256];
+ int tmp;
+
+ strcpy(buf,CINIT_DIR);
+ tmp = strlen(CINIT_DIR);
+ buf[tmp] = '/';
+ strcpy(&buf[tmp+1],C_INIT);
+
+ printf("path: %s\n",buf);
+
+ run_svc("/etc/cinit/init");
+
+ run_svc("/NOT_THERE");
+
+ return 0;
+
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.c03 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c03
new file mode 100644
index 00000000..c1b5eb42
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c03
@@ -0,0 +1,241 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux
+ */
+
+#define CINIT_DIR "/etc/cinit"
+
+#define C_INIT "init"
+#define C_SHD "shutdown"
+#define C_REBOOT "reboot"
+
+#define C_NEEDS "needs"
+#define C_WANTS "wants"
+#define C_RUN "run"
+
+/* opendir() */
+#include
+#include
+
+/* *stat() */
+#include
+#include
+
+/* wait() */
+#include
+
+/* strlen */
+#include
+
+#include
+
+#include "cinit.h"
+
+#define EKEL "/etc/cinit/init/wants"
+
+/* status of a service */
+#define ST_TMP 1 /* currently working on it */
+#define ST_ONCE 2 /* executed once */
+#define ST_RESPAWN 3 /* running and respawning */
+
+/* array of svc */
+/* linked list of services */
+/* balanced trees */
+struct svc {
+ char *abs_path;
+// struct svc *next;
+ int status; /* tmp, respawn, ran once */
+ /* evtl: */
+};
+
+struct svcl {
+ struct svc svc_list[1000];
+ int process;
+} svc_list;
+
+void cerr(char *msg)
+{
+ printf("%s\n", msg);
+}
+
+/***********************************************************************
+ * parallel run forked() run_svc()
+ */
+#define MAX_PAR 32
+
+int run_run_svcs(char *rpath)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ pid_t pids[MAX_PAR];
+ int tmp,i=0;
+
+ printf("run_run_svcs on: %s\n",rpath);
+
+ d_tmp = opendir(rpath);
+
+ if(d_tmp == NULL) {
+ printf("Failed to open dir: %s", rpath);
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0
+ || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ if(i < MAX_PAR) {
+ pids[i] = fork();
+ i++;
+ } else {
+ cerr("to many dependencies");
+ return 1;
+ }
+
+ if(pids[i-1] == -1) { /* err */
+ cerr("fork failed\n");
+ return 0;
+ } else if(pids[i-1] == 0) { /* child */
+ printf("Service zu starten nun: %s\n", tdirent->d_name);
+ run_svc(tdirent->d_name);
+ _exit(0);
+ } else /* the parent simply goes the loop again */
+ printf("run_svcs_PARENT\n");
+ }
+
+ closedir(d_tmp);
+
+ /* wait for pids */
+ while(i >= 0) {
+// printf("waiting for %d ... \n",i);
+ waitpid(pids[i], &tmp, 0);
+ i--;
+ }
+}
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether _one_ service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+ /* check if already running / ran / currently starting */
+
+ /* debug */
+ getcwd(pathbuf,1024);
+
+ printf("dir: %s\n",pathbuf);
+
+ /* check for service dir */
+ if( stat(path,&buf) ) {
+ printf("no such service: %s\n", path);
+ return 1;
+ }
+
+ /* check for needs -> forked() */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathbuf);
+ tmp = fork();
+ if(tmp == -1) {
+ printf("error ...\n");
+ exit(1);
+ } else if(tmp == 0) { /* child */
+ printf("child for run_run_svcs()\n");
+ run_run_svcs(pathbuf);
+ _exit(0);
+ printf("ZOOOMBIE\n");
+ }
+ else
+ printf("parent\n");
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathbuf);
+ run_run_svcs(pathbuf);
+ }
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ cerr("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
+
+/***********************************************************************
+ * the main procedure
+ */
+
+int main()
+{
+ char pathbuf[MAXPATH];
+ struct stat buf;
+
+ strcpy(pathbuf,CINIT_DIR);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_INIT);
+
+ printf("path: %s\n",pathbuf);
+
+ svc_list.process = 0;
+
+ /* stat, checkdir */
+ if( stat(pathbuf,&buf) ) {
+ printf("PANIC ACTION: init dir missing\n");
+ return 1;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("PANIC ACTION: init is not a dir\n");
+ return 1;
+ }
+
+ if( chdir(pathbuf) == -1) {
+ printf("PANIC ACTION: chdir(%s) failed!\n",pathbuf);
+ return 1;
+ }
+ run_svc("/etc/cinit/init");
+// run_svc("");
+
+// run_svc("/NOT_THERE");
+
+// execl("/bin/zsh","zsh", "-l");
+
+ return 0;
+
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.c04 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c04
new file mode 100644
index 00000000..983c03eb
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c04
@@ -0,0 +1,130 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux
+ */
+
+/* *stat() */
+#include
+#include
+
+/* open */
+#include
+
+/* siggnal */
+#include
+
+/* PATH_MAX */
+#include
+
+/* printf() */
+//#include
+
+/* str* */
+#include
+
+#include "cinit.h"
+
+/* global variable */
+struct svcl svc_list;
+int f_in, f_out;
+
+/***********************************************************************
+ * the main procedure
+ */
+
+int main()
+{
+ char pathbuf[PATH_MAX];
+ char buf[1223];
+ struct stat sbuf;
+ int i;
+
+ struct sigaction sa;
+
+ /* signal handlers to ignore */
+ sa.sa_handler=SIG_IGN;
+// sigaction(SIGINT,&sa,NULL); /* ignore ctr+c */
+ sigaction(SIGSTP,&sa,NULL); /* ignore ctr+z, stop */
+
+ D_PRINTF(CINIT_INIT);
+
+ /* count of started processes */
+ svc_list.process = 0;
+
+ /* begin to handle signals */
+
+ /* stat, checkdir */
+ if( stat(CINIT_INIT,&sbuf) ) {
+ cerr("PANIC ACTION: init dir missing", RT_PAR_FAIL);
+ } else if( ! S_ISDIR(sbuf.st_mode) ) {
+ cerr("PANIC ACTION: init is not a dir", RT_PAR_FAIL);
+ }
+
+ if( chdir(CINIT_INIT) == -1)
+ cerr("PANIC ACTION: chdir to /etc/cinit/init failed!",RT_PAR_FAIL);
+
+ /* open communication fifos */
+ f_in = open(CINIT_DIR SLASH F_IN, O_RDWR);
+ f_out = open(CINIT_DIR SLASH F_OUT, O_RDWR);
+ if(f_in == -1 || f_out == -1) cerr("opening fifo failed\n",RT_PAR_FAIL);
+
+ /* initial run, only if we are 'real' init' */
+// if( getpid() == 1) {
+ i = run_init_svc();
+ printf("Initialer Start rueckgabe: %d\n", i);
+// }
+
+ /* signal handlers to do special things with */
+ // something else sa.sa_handler=SIG_IGN;
+ sigaction(SIGUSR1,&sa,NULL); /* reboot on sigusr1 */
+ sigaction(SIGUSR1,&sa,NULL); /* power-off on sigusr2 */
+ sigaction(SIGTERM,&sa,NULL); /* halt on sigterm */
+
+ /* important signal handlers: pipe, child */
+// sa.sa_handler=sig_pipe;
+// sigaction(SIGPIPE,&sa,NULL); /* what todo when pipe/fifo closed */
+
+// sa.sa_handler=sig_child;
+// sigaction(SIGCHLD,&sa,NULL); /* what todo when child exited */
+
+
+ /* big TODO: */
+
+ /* some while/for loop to hang forever, remember, we are init! */
+ while(1) {
+ i=0;
+ /* read path */
+ do {
+ read(f_in,&buf,1);
+// buf1[i] = buf; i++;
+ } while(buf != '\0');
+//
+ // printf("Read path: %s\n",buf1);
+
+ i=0;
+ /* read status */
+ do {
+ read(f_in,&buf,1);
+ // buf2[i] = buf; i++;
+ } while(buf != '\0');
+
+ // status = atoi(buf2);
+ // printf("Read status: %d\n",status);
+
+ i=0;
+ /* read pid */
+ do {
+ read(f_in,&buf,1);
+ // buf3[i] = buf; i++;
+ } while(buf != '\0');
+
+ // pid = atoi(buf3);
+
+
+
+ }
+
+ return 0;
+
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.c05 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c05
new file mode 100644
index 00000000..8dec1f46
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c05
@@ -0,0 +1,137 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux/cinit
+ */
+
+/* *stat() */
+#include
+#include
+
+/* open */
+#include
+
+/* siggnal */
+#include
+
+/* PATH_MAX */
+#include
+
+/* printf() */
+//#include
+
+/* str* */
+#include
+
+#include "cinit.h"
+
+/* global variable */
+struct svcl svc_list;
+
+/***********************************************************************
+ * the main procedure
+ */
+
+int main()
+{
+ char buf[1223];
+ struct stat sbuf;
+ int i;
+
+ struct sigaction sa;
+
+ /* signal handlers to ignore */
+ sa.sa_handler=SIG_IGN;
+// sigaction(SIGINT,&sa,NULL); /* ignore ctr+c */
+ sigaction(SIGSTOP,&sa,NULL); /* ignore ctr+z, stop */
+ sigaction(SIGPIPE,&sa,NULL); /* what todo when pipe/fifo closed */
+
+ D_PRINTF(CINIT_INIT);
+
+ /* begin to handle signals */
+
+ /* stat, checkdir */
+ if( stat(CINIT_INIT,&sbuf) ) {
+ cerr("PANIC ACTION: init dir missing", RT_PAR_FAIL);
+ } else if( ! S_ISDIR(sbuf.st_mode) ) {
+ cerr("PANIC ACTION: init is not a dir", RT_PAR_FAIL);
+ }
+
+ if( chdir(CINIT_INIT) == -1)
+ cerr("PANIC ACTION: chdir to /etc/cinit/init failed!",RT_PAR_FAIL);
+
+ /* get shared memory */
+
+ shmfd = shm_open(CINIT_SHM,O_RDWR|O_CREAT,0600);
+
+ if(shmfd == -1) {
+ perror("Shared memory");
+ cerr("shared memory",RT_PAR_FAIL);
+ }
+
+ /* count of started processes */
+ svc_list.process = 0;
+
+ /* open communication fifos */
+ f_in = open(CINIT_DIR SLASH F_IN, O_RDWR);
+ f_out = open(CINIT_DIR SLASH F_OUT, O_RDWR);
+ if(f_in == -1 || f_out == -1) cerr("opening fifo failed",RT_PAR_FAIL);
+
+ /* initial run, only if we are 'real' init' */
+// if( getpid() == 1) {
+ i = run_init_svc();
+ printf("Initialer Start rueckgabe: %d\n", i);
+// }
+
+ /* signal handlers to do special things with */
+ // something else sa.sa_handler=SIG_IGN;
+ sigaction(SIGUSR1,&sa,NULL); /* reboot on sigusr1 */
+ sigaction(SIGUSR1,&sa,NULL); /* power-off on sigusr2 */
+ sigaction(SIGTERM,&sa,NULL); /* halt on sigterm */
+
+ /* important signal handlers: pipe, child */
+// sa.sa_handler=sig_pipe;
+
+// sa.sa_handler=sig_child;
+// sigaction(SIGCHLD,&sa,NULL); /* what todo when child exited */
+
+
+ /* big TODO: */
+
+ /* some while/for loop to hang forever, remember, we are init! */
+ while(1) {
+ i=0;
+ /* read path */
+ do {
+ read(f_in,&buf,1);
+// buf1[i] = buf; i++;
+ } while(buf != '\0');
+//
+ // printf("Read path: %s\n",buf1);
+
+ i=0;
+ /* read status */
+ do {
+ read(f_in,&buf,1);
+ // buf2[i] = buf; i++;
+ } while(buf != '\0');
+
+ // status = atoi(buf2);
+ // printf("Read status: %d\n",status);
+
+ i=0;
+ /* read pid */
+ do {
+ read(f_in,&buf,1);
+ // buf3[i] = buf; i++;
+ } while(buf != '\0');
+
+ // pid = atoi(buf3);
+
+
+
+ }
+
+ return 0;
+
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.c06 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c06
new file mode 100644
index 00000000..c48de22c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.c06
@@ -0,0 +1,158 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux/cinit
+ */
+
+/* *stat() */
+#include
+#include
+
+/* open */
+#include
+
+/* siggnal */
+#include
+
+/* PATH_MAX */
+#include
+
+/* printf() */
+//#include
+
+/* str* */
+#include
+
+/* sockets */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* global variable */
+struct svcl svc_list;
+int sock;
+
+/***********************************************************************
+ * sigio: client handling
+ */
+
+/* we are called, if one or _more_ connections are waiting */
+void sigio(int signal)
+{
+ struct ucred suck;
+ int len = sizeof(suck), lens;
+ int nsock;
+ struct sockaddr_un sun;
+ char buf;
+
+ lens=sizeof(sun);
+ memset(&sun,0,lens);
+
+/* this is always us! */
+// getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &suck, &len);
+// printf("orig angreifer: pid: %d uid: %d gid: %d\n",suck.pid,suck.uid,suck.gid);
+
+ do {
+ //s_tmp[s_idx] = accept(sock,(struct sockaddr *) &sun, (socklen_t *) &lens);
+ nsock = accept(sock,(struct sockaddr *) NULL, (socklen_t *) NULL);
+
+ // nsock = accept(sock,(struct sockaddr *) &sun, (socklen_t *) &lens);
+// if( s_tmp[s_idx] == -1) {
+ if( nsock == -1) {
+ if (errno != EAGAIN) {
+ perror("accept");
+ _exit(1);
+ } else {
+ break;
+ }
+ }
+
+ //getsockopt(s_tmp[s_idx], SOL_SOCKET, SO_PEERCRED, &suck, &len);
+ getsockopt(nsock, SOL_SOCKET, SO_PEERCRED, &suck, &len);
+ printf("angreifer: pid: %d uid: %d gid: %d\n",suck.pid,suck.uid,suck.gid);
+
+
+ read(nsock,&buf,1);
+
+ printf("command: %d\n",buf);
+
+ while ( (len = read(nsock,&buf,1)) ) {
+// printf("laenge: %d\n",len);
+ if(len == -1) {
+// if(errno != EINVAL && errno != EAGAIN) {
+ perror("read");
+ return;
+// _exit(1);
+// }
+ }
+ if(buf == 0) break;
+ write(1,&buf,1);
+ }
+ printf("Fertig mit lesen\n");
+
+ write(nsock,"ok\n",4);
+ printf("fertig mit schreiben\n");
+ } while ( 1 );
+
+ printf("keine sockets mehr da..., sigio beendet sich jetzt.\n");
+}
+
+/***********************************************************************
+ * the main procedure
+ */
+
+int main()
+{
+ struct stat sbuf;
+ int i;
+
+ struct sigaction sa;
+
+ /* signal handlers to ignore */
+ sa.sa_handler=SIG_IGN;
+// sigaction(SIGINT,&sa,NULL); /* ignore ctr+c */
+ sigaction(SIGSTOP,&sa,NULL); /* ignore ctr+z, stop */
+ sigaction(SIGPIPE,&sa,NULL); /* what todo when pipe/fifo closed */
+ sigaction(SIGCHLD,&sa,NULL); /* what todo when child exited */
+
+ sa.sa_handler=sigio;
+ sigaction(SIGIO,&sa,NULL); /* what todo when data arrived on socket */
+
+ D_PRINTF(CINIT_INIT);
+
+ /* stat, checkdir */
+ if( stat(CINIT_INIT,&sbuf) ) {
+ cerr("PANIC ACTION: init dir missing", RT_PAR_FAIL);
+ } else if( ! S_ISDIR(sbuf.st_mode) ) {
+ cerr("PANIC ACTION: init is not a dir", RT_PAR_FAIL);
+ }
+
+ if( chdir(CINIT_INIT) == -1)
+ cerr("PANIC ACTION: chdir to /etc/cinit/init failed!",RT_PAR_FAIL);
+
+ /* count of started processes */
+ svc_list.process = 0;
+
+ /* initial run, only if we are 'real' init' */
+// if( getpid() == 1) {
+ i = run_init_svc();
+ printf("Initialer Start rueckgabe: %d\n", i);
+// }
+
+ /* signal handlers to do special things with */
+ // something else sa.sa_handler=SIG_IGN;
+// sigaction(SIGUSR1,&sa,NULL); /* reboot on sigusr1 */
+// sigaction(SIGUSR1,&sa,NULL); /* power-off on sigusr2 */
+// sigaction(SIGTERM,&sa,NULL); /* halt on sigterm */
+
+ /* the main loop */
+ while(1) ;
+
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.commands.v01 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.commands.v01
new file mode 100644
index 00000000..dfdb67c5
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.commands.v01
@@ -0,0 +1,85 @@
+--------------------------------------------------------------------------------
+cinit commands, Nico Schottelius 2005-04-28
+--------------------------------------------------------------------------------
+
+cinit allows communication through a socket (see ipc.thoughs for reasons).
+
+Sockets allow to find out the accessing uid, gid and pid (uses SO_PEERCRED as
+socketoption).
+
+The communication-protocol is binary.
+
+--------------------------------------------------------------------------------
+Protocol overview
+--------------------------------------------------------------------------------
+
+Any communication begins with a command. A command is a one byte
+unsigned char. Depending on the command, the communication has its own
+semantics.
+
+
+Commands are: (values can be found in cinit.h)
+
+ CMD_START_SVC: I want to start a service.
+ CMD_CHG_STATUS: I want to change the status of a service.
+ CMD_STOP_SVC: Please shutdown a service and its dependencies.
+ CMD_KILL_SVC: Shutdown a service, don't care about its dependencies.
+
+ CMD_RESCUE: Kill everything, and spawn a sulogin shell.
+ CMD_INIT: Start all services (again possibly).
+
+ CMD_HALT: Halt the system.
+ CMD_REBOOT: Reboot the system.
+ CMD_POWEROFF: Power-off the system.
+
+--------------------------------------------------------------------------------
+Detailled command-listing
+--------------------------------------------------------------------------------
+
+CMD_START_SVC
+ 1. int len; /* length of service name, including \0 */
+ 2. char *svc; /* name of the service, absolute pathname */
+
+ cinit returns:
+ a) ok, a SID, a service ID: int svc_id; [ really need int? ]
+ b) fail, [currently only fail is returned]
+ a) already running
+ b) svc_name too long / not allowed
+
+ [ A service identification is used for faster searching in cinit.
+ It is also a hint for developers of external software, that they should not
+ be able to use CMD_CHG_STATUS, if they didn't start a service.
+ They should use CMD_STOP_SVC to stop a service.
+ Starting a service is currently done via exec() in the external program or
+ a cinit-fork(). ]
+
+CMD_CHG_STATUS: I want to change the status of a service.
+ 0. int svc_id; /* service ID to change */
+ 1. char status; /* status:
+ once: started successfully the service once.
+ fail: tried to start once, but the service exit uncgrafully
+ UNUSED! respawn: I am on it, as soon it exists I'll restart! */
+ 2. pid_t pid /* the pid of the service, if started once
+ or the pid of the service watcher, if respawning */
+
+ cinit returns: MSG_OK|MSG_FAIL (char)
+
+CMD_STOP_SVC: Please shutdown a service and its dependencies.
+ 1. int len; /* length of service name, including \0 */
+ 2. char *svc; /* name of the service, absolute pathname */
+
+ cinit returns: ready...
+
+CMD_KILL_SVC: Shutdown a service, don't care about its dependencies.
+ 1. int len; /* length of service name, including \0 */
+ 2. char *svc; /* name of the service, absolute pathname */
+
+ cinit returns: ready...
+
+CMD_INIT: Start all services (again possibly).
+ cinit returns: ready...
+
+CMD_RESCUE: Kill everything, and spawn a sulogin shell.
+CMD_HALT: Halt the system.
+CMD_REBOOT: Reboot the system.
+CMD_POWEROFF: Power-off the system.
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.create.cinit_dir b/software/cinit/browse_source/cinit-0.0.4/old/cinit.create.cinit_dir
new file mode 100644
index 00000000..6fd58adb
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.create.cinit_dir
@@ -0,0 +1,11 @@
+#!/bin/sh
+# Nico Schottelius
+# cinit: create our initial directory
+# 2005-05-24
+
+# init variables
+. $(dirname $0)/cinit.read-conf
+
+BASEDIR=$DESTDIR/$CINIT_DIR
+
+mkdir -p $BASEDIR
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cinit.h01 b/software/cinit/browse_source/cinit-0.0.4/old/cinit.h01
new file mode 100644
index 00000000..e07fa2c1
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cinit.h01
@@ -0,0 +1,80 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * header of cinit
+ */
+
+/* includes */
+#include /* pid_t */
+
+/* limits */
+#define MAX_SVC 1024 /* maximum services */
+#define MAX_DEPS 32 /* maximum direct dependencies of a service */
+
+/* paths */
+#define CINIT_DIR "/etc/cinit"
+
+#define F_IN "in"
+#define F_OUT "out"
+#define SLASH "/"
+
+#define C_INIT "init"
+#define C_SHD "shutdown"
+#define C_REBOOT "reboot"
+
+#define C_NEEDS "./needs"
+#define C_WANTS "./wants"
+#define C_RUN "./run"
+#define C_RESPAWN "respawn"
+#define C_PARAMS "params"
+
+/* return values */
+#define RT_FAIL 0
+#define RT_OK 1
+
+#define RT_CHLD_FAIL 1 /* child failed */
+#define RT_CHLD_OK 2 /* child succeded */
+#define RT_PAR_FAIL 3 /* parent failed */
+#define RT_PAR_OK 4 /* parent succeded */
+
+/* status of a service-starter (run_run_svc) */
+#define RT_ONE_FAILED 5 /* one ore more failed */
+#define RT_ALL_STARTED 6 /* everything ok */
+#define RT_DEPS_MAX 7 /* too many dependencies */
+
+/* status of a service */
+#define ST_NO 0 /* process not existing */
+#define ST_TMP 1 /* currently working on it */
+#define ST_ONCE 2 /* executed once */
+#define ST_RESPAWN 3 /* running and respawning */
+#define ST_FAIL 4 /* failed to start service */
+
+
+
+/* variables */
+
+/* array of svc */
+/* linked list of services */
+/* balanced trees */
+
+struct svc {
+ char *abs_path; /* service identifier */
+ int status; /* tmp, respawn, ran once */
+ pid_t pid; /* pid of the process */
+};
+
+struct svcl {
+ struct svc svca[MAX_SVC];
+ int process;
+};
+
+extern struct svcl svc_list;
+
+/* functions */
+
+void cerr(char *string, int status);
+int chk_svc(char *svc);
+int run_svc(char *rpath);
+int add_mod_svc(char *svc, int status);
+int run_run_svcs(char *rpath);
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/cnt_digits.c b/software/cinit/browse_source/cinit-0.0.4/old/cnt_digits.c
new file mode 100644
index 00000000..a692fa5c
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/cnt_digits.c
@@ -0,0 +1,42 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * cinit.c
+ * part of cLinux/cinit
+ */
+
+/* this code is stolen from gpm */
+
+/* what's the english name for potenz ? */
+int x_high_y(int base, int pot_y)
+{
+ int val = 1;
+
+ if(pot_y == 0) val = 1;
+ else if(pot_y < 0) val = 0; /* ugly hack ;) */
+ else while(pot_y > 0) {
+ val = val * base;
+ pot_y--;
+ }
+ return val;
+}
+
+/* return characters needed to display int */
+int cnt_digits(int number)
+{
+ /* 0-9 = 1 10^0 <-> (10^1)-1
+ * 10 - 99 = 2 10^1 <-> (10^2)-1
+ * 100 - 999 = 3 10^2 <-> (10^3)-1
+ * 1000 - 9999 = 4 ... */
+
+ int ret = 0, num = 0;
+
+ /* non negative, please */
+ if(number < 0) number *= -1;
+ else if(number == 0) ret = 1;
+ else while(number > num) {
+ ret++;
+ num = (x_high_y(10,ret) - 1);
+ }
+
+ return(ret);
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/do_change_status.c01 b/software/cinit/browse_source/cinit-0.0.4/old/do_change_status.c01
new file mode 100644
index 00000000..74bb9c1e
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/do_change_status.c01
@@ -0,0 +1,65 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * change status of a service
+ * part of cinit
+ */
+
+#include
+#include
+#include
+
+#include "cinit.h"
+
+/* one handler for read and write! */
+int do_change_status(char *svc, char *status, pid_t *pid, int sock2, int action)
+{
+ char buf = CMD_CHG_STATUS;
+ int tmp;
+ ssize_t (*fpoint)(int,void* ,size_t);
+
+ D_PRINTF("VERSUCHE STATUS ZU AENDERN");
+ printf("socket: %d (cmd=%d)\n",sock2, buf);
+
+ if(action == ACT_READ) {
+ D_PRINTF("Leeeese");
+ fpoint = read;
+ } else {
+ D_PRINTF("schreibe");
+ fpoint = write; /* don't care about warnings! */
+ }
+
+ if(action == ACT_WRITE) {
+ D_PRINTF("schreibe kommando");
+ if(fpoint(sock2,&buf,1) == -1) { /* COMMAND */
+ perror("command i/o");
+ return 0;
+ }
+ tmp = strlen(svc);
+ sock2 = connect_sock(sock2);
+ }
+
+ if(fpoint(sock2,&tmp,sizeof(tmp)) == -1) { /* length */
+ perror("i/o: length");
+ return 0;
+ }
+
+ if(fpoint(sock2,svc,tmp) == -1) { /* write service name */
+ perror("i/o: service name");
+ return 0;
+ }
+
+ if(fpoint(sock2,status,sizeof(*status)) == -1) { /* status */
+ perror("i/o: status");
+ printf("Status: %d, *status=%d, sizeof=%d\n",status,*status,sizeof(*status));
+ return 0;
+ }
+
+ if(fpoint(sock2,pid,sizeof(*pid)) == -1) { /* PID */
+ perror("i/o: PID");
+ return 0;
+ }
+
+ D_PRINTF("fertig mit statuswechsel lesen");
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/idea01 b/software/cinit/browse_source/cinit-0.0.4/old/idea01
new file mode 100644
index 00000000..cf0df9d6
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/idea01
@@ -0,0 +1,121 @@
+--------------------------------------------------------------------------------
+/etc/cinit
+ -> init/
+ -> shutdown/
+ -> reboot/
+
+
+ needs/ -> we wait until all parallel processes are finished _and_ we
+ don't start if one fails
+ wants/ -> we start all of them parallel and wait for them?
+ hold/
+ wait -> wait until process finished
+ run -> program to execute
+ params -> \n seperated argument list
+ respawn -> respawn it
+
+services may only be under /etc/cinit?
+--------------------------------------------------------------------------------
+Service-Status:
+
+- abs_path
+- status (respawn,tmp,once)
+--------------------------------------------------------------------------------
+
+starting services:
+
+run_svc("/etc/cinit/service/")
+ -> exec run $params
+Later:
+ -> check if service already running -> return OK
+ -> check needs/ -> check wants/
+ -> run_svc($cur)
+
+ When run_svc returns, the service is started and all service it needs, too.
+
+
+--------------------------------------------------------------------------------
+ -> check needs/
+ -> exists -> fork( run_run_svcs() ) and continue
+ (fork) -> fork() run_svc(needs/*);
+ -> check wants/
+ -> exists -> run_svc(wants/*);
+ -> waitfor(need_run_svc)
+--------------------------------------------------------------------------------
+run_run_svcs()
+ -> start parallel (forked) run_svc() for every service
+--------------------------------------------------------------------------------
+
+main()
+ - run_svc /etc/cinit/init/
+ - sleep()? -> simply do nothing -> do we need to fork ourselves? No, we are init.
+spaeter:
+ - open /dev/console W_ONLY
+ - make stdin == /etc/cinit/in
+ - make stdout, stderr /dev/console
+
+--------------------------------------------------------------------------------
+eof
+
+Things, which are clear
+
+- we need to fork before execl(), as excel() replaces us.
+- chdir() _after_ fork()
+
+
+profiles support: profile=$profile
+
+ start
+ "service.$profile" if exists, instead of
+ "service"
+
+starting services:
+
+cinit:
+ pipe()
+ set_status_tmp()
+ fork() --> failure --> clear_service
+ cinit_process_watcher():
+ fork()
+ execve(process,args,env)
+ waitpid() -> for once? PROCESS MUST RETURN!
+ write_pipe()
+ rmpipe()
+
+--------------------------------------------------------------------------------
+
+What to send over to cinit and read back?
+
+ - first you need two pipes for every process: read+write (on both sides)
+ - cinit wants
+ o command
+ - service temporary - trying to start in right now.
+ - service executed once - fine
+ - service executed once and that failed - :-(
+ - service respawing
+ o an identifier for the service (i from service list ;-)
+
+ --> makes 2 bytes to read
+--------------------------------------------------------------------------------
+How cinit works:
+
+cinit says: I want to start service xyz. (/etc/cinit/init on bootup)
+cinit calls run_svc().
+--------------------------------------------------------------------------------
+
+run_svc(char *relative_path):
+ - check if service is alr
+ - fork()
+ - write cinit: check service, I want to start it
+ -> returns status of service (see ST_* in cinit.h)
+ - cinit returns: ok, you are temporary
+ - [that checked] check if service
+ o is already started
+ o is beeing started
+ x check if rpath S_ISDIR
+ x chdir(dir)
+ - check needs - check wants
+ - for every needs/* start run_svc
+ - check respawn -> respawn = true
+ - check run
+
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/idea02 b/software/cinit/browse_source/cinit-0.0.4/old/idea02
new file mode 100644
index 00000000..38af8965
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/idea02
@@ -0,0 +1,200 @@
+--------------------------------------------------------------------------------
+/etc/cinit
+ -> init/
+ -> shutdown/
+ -> reboot/
+
+
+ needs/ -> we wait until all parallel processes are finished _and_ we
+ don't start if one fails
+ wants/ -> we start all of them parallel and wait for them?
+ hold/
+ wait -> wait until process finished
+ run -> program to execute
+ params -> \n seperated argument list
+ respawn -> respawn it
+
+services may only be under /etc/cinit?
+--------------------------------------------------------------------------------
+Service-Status: (see struct svc, cinit.h)
+
+- abs_path
+- status (respawn,tmp,once)
+- pid
+
+abs_path\0status\0pid\0
+
+--------------------------------------------------------------------------------
+
+starting services:
+
+run_svc("/etc/cinit/service/")
+ -> exec run $params
+Later:
+ -> check if service already running -> return OK
+ -> check needs/ -> check wants/
+ -> run_svc($cur)
+
+ When run_svc returns, the service is started and all service it needs, too.
+
+
+--------------------------------------------------------------------------------
+ -> check needs/
+ -> exists -> fork( run_run_svcs() ) and continue
+ (fork) -> fork() run_svc(needs/*);
+ -> check wants/
+ -> exists -> run_svc(wants/*);
+ -> waitfor(need_run_svc)
+--------------------------------------------------------------------------------
+run_run_svcs()
+ -> start parallel (forked) run_svc() for every service
+--------------------------------------------------------------------------------
+
+main()
+ - run_svc /etc/cinit/init/
+ - sleep()? -> simply do nothing -> do we need to fork ourselves? No, we are init.
+spaeter:
+ - open /dev/console W_ONLY
+ - make stdin == /etc/cinit/in
+ - make stdout, stderr /dev/console
+
+--------------------------------------------------------------------------------
+eof
+
+Things, which are clear
+
+- we need to fork before execl(), as excel() replaces us.
+- chdir() _after_ fork()
+
+
+profiles support: profile=$profile
+
+ start
+ "service.$profile" if exists, instead of
+ "service"
+
+starting services:
+
+cinit:
+ pipe()
+ set_status_tmp()
+ fork() --> failure --> clear_service
+ cinit_process_watcher():
+ fork()
+ execve(process,args,env)
+ waitpid() -> for once? PROCESS MUST RETURN!
+ write_pipe()
+ rmpipe()
+
+--------------------------------------------------------------------------------
+
+What to send over to cinit and read back?
+
+ - first you need two pipes for every process: read+write (on both sides)
+ - cinit wants
+ o command
+ - service temporary - trying to start in right now.
+ - service executed once - fine
+ - service executed once and that failed - :-(
+ - service respawing
+ o an identifier for the service (i from service list ;-)
+
+ --> makes 2 bytes to read
+--------------------------------------------------------------------------------
+How cinit works:
+
+cinit says: I want to start service xyz. (/etc/cinit/init on bootup)
+cinit calls run_svc().
+--------------------------------------------------------------------------------
+
+int run_svc(char *relative_path):
+ - check if service is already running or temporary (task list!)
+ -> yes: return RT_PAR_OK
+ -> no: continue.
+ - set service to be temporary (ST_TMP) and retrieve SID (service ID)
+ - walk through dependency tree and call run_svc
+ - fork() -> so cinit can continue.
+ - write cinit: check service, I want to start it
+ -> returns status of service (see ST_* in cinit.h)
+ - cinit returns: ok, you are temporary
+ - [that checked] check if service
+ o is already started
+ o is beeing started
+ x check if rpath S_ISDIR
+ x chdir(dir)
+ - check needs - check wants
+ - for every needs/* start run_svc
+ - check respawn -> respawn = true
+ - check run
+
+--------------------------------------------------------------------------------
+
+add_mod_svc(char *svc, int status)
+ -> add or modify status of a service
+
+ - check whether service exists, reset status
+ - if not exists, insert if maximum of services is not reached
+--------------------------------------------------------------------------------
+
+cinit communications proto
+--------------------------------------------------------------------------------
+
+cinit:
+ -> signal_handler on SIGCHLD
+ run_init()
+ -> run_svc(init)
+ -> fork() -> do the work
+
+signal_handler_child
+ waitpid(.*)
+ -> returns pid
+
+ oder waitpid() in dem run_svc, wenn need/once?
+
+ need:
+ for i in need/*; do
+ ( $service & );
+ done
+ wait(.*);
+
+--------------------------------------------------------------------------------
+
+cinit:
+
+run_svc:
+ checks what it needs (need/*)
+ need/*
+ fork()
+ fork(), fork()
+
+--------------------------------------------------------------------------------
+Kommunikationsproblem:
+
+ -> 1024 ist maximale anzahl offener sockets -> 510 von fifos,pipes
+ - mehrere FIFOs?
+ --> kommunikation gesichert, extrem viele fifos...
+ --> etwas unsauber, aber geregelte kommunikation
+ - mehrere PIPEs?
+ --> viele PIPEs (HRHR)
+ --> programme koennen nur von cinit gefork()ed werden.
+
+ --> eine datei mit prozessen?
+ --> einen RAM Bereich?
+--------------------------------------------------------------------------------
+
+cinit[1] <-> fifo <-> forker
+
+forker?
+--------------------------------------------------------------------------------
+
+pfad vorher aufloesen?
+
+--------------------------------------------------------------------------------
+Kommunikation: ::Test::
+
+ Test mit nur 2 FIFOs!
+
+--------------------------------------------------------------------------------
+
+sig_fifo()
+read(..) als hauptaufgabe?
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/msg_change_status.c01 b/software/cinit/browse_source/cinit-0.0.4/old/msg_change_status.c01
new file mode 100644
index 00000000..cfd66ae3
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/msg_change_status.c01
@@ -0,0 +1,49 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * change status of a service
+ * part of cinit
+ */
+
+#include
+#include
+
+#include "cinit.h"
+
+int do_change_status(char *svc, char status, pid_t pid, int action)
+{
+ char buf = CMD_CHG_STATUS;
+ int tmp = strlen(svc);
+ ssize_t (*fpoint)(int,void* ,size_t);
+
+
+ if(action == ACT_READ)
+ fpoint = read;
+ else
+ fpoint = write;
+
+ D_PRINTF("versuche status zu aendern");
+
+ if(write(sock,&buf,1) == -1) { /* write COMMAND */
+ perror("write");
+ return 0;
+ }
+ if(write(sock,&tmp,sizeof(tmp)) == -1) { /* write length */
+ perror("write");
+ return 0;
+ }
+ if(write(sock,svc,tmp) == -1) { /* write service name */
+ perror("write");
+ return 0;
+ }
+ if(write(sock,&buf,1) == -1) { /* write PID */
+ perror("write");
+ return 0;
+ }
+ write(sock,&status,sizeof(status)); /* write status */
+
+ D_PRINTF("fertig mit schreiben");
+
+ read(sock,&buf,sizeof(buf)); /* read SID or -1 if error */
+
+ return buf;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/msg_start_svc.c b/software/cinit/browse_source/cinit-0.0.4/old/msg_start_svc.c
new file mode 100644
index 00000000..c6a78bf8
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/msg_start_svc.c
@@ -0,0 +1,23 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * tell cinit we start a service
+ */
+
+#include
+
+/* return status */
+int msg_start_svc(char *string, int respawn)
+{
+ char *p;
+
+ p = string;
+ while ( *p != '\0') {
+ write(2,p,1);
+ p++;
+ }
+
+/* FIXME: return if in cinit, _exit on fork() */
+// if(...)
+ _exit(status);
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/read_file.c b/software/cinit/browse_source/cinit-0.0.4/old/read_file.c
new file mode 100644
index 00000000..43a5854b
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/read_file.c
@@ -0,0 +1,100 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+
+#include "cinit.h"
+
+/***********************************************************************
+ * read_file: return file content, each line a char*
+ */
+
+char **read_file(char *file)
+{
+ int tmp;
+ int fd, argc;
+
+ char buf[BUFSIZE];
+ char *p, *sbuf = NULL;
+ char **nargv = NULL;
+
+ struct stat stbuf;
+
+ D_PRINTF("Lese Datei");
+ D_PRINTF(file);
+
+ if( !stat(file,&stbuf) ) {
+ fd = open(file,O_RDONLY);
+
+ if(fd == -1) {
+ LOG("params exists, but open params failed");
+ return NULL;
+ }
+
+ D_PRINTF("open ist ok");
+
+ argc = 0;
+
+ /* most likely one round */
+ while ( (tmp = read(fd,buf,BUFSIZE) ) != 0 ) {
+ if(tmp == -1) {
+ perror("read");
+ return NULL;
+ }
+
+ sbuf = realloc(sbuf,argc + tmp + 1);
+ strncpy(&sbuf[argc],buf,tmp);
+ argc += tmp;
+ }
+ close(fd);
+ }
+
+ sbuf[argc] = '\0';
+
+ /************** build string **************/
+ /* The idea is to reuse the allocated memory. We'll simply
+ * replace the \n with \0 and set a char* to it.
+ * We'll lose the last byte (the initial \0), but we
+ * don't care, as we die some seconds later with execv() */
+
+ argc = 0;
+
+ while( (p = strchr(sbuf,'\n')) ) {
+ nargv = realloc(nargv, sizeof(char *) * (argc + 1));
+
+ if(nargv == NULL) {
+ LOG("realloc failed");
+ return NULL;
+ }
+
+ nargv[argc] = sbuf;
+ *p = '\0';
+ sbuf = p+1; /* is ok, as behind the last \n is a \0 */
+ argc++;
+ }
+
+ /************ close argv list **************/
+ nargv = realloc(nargv, sizeof(char *) * (argc + 1));
+ if(nargv == NULL) {
+ LOG("realloc failed");
+ return NULL;
+ }
+
+ nargv[argc] = NULL; /* terminate argv list */
+
+ return nargv;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_init_svc.c01 b/software/cinit/browse_source/cinit-0.0.4/old/run_init_svc.c01
new file mode 100644
index 00000000..61467f44
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_init_svc.c01
@@ -0,0 +1,50 @@
+/*
+ * cinit
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run initial service
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cinit.h"
+
+
+/***********************************************************************
+ * start the first service
+ */
+
+int run_init_svc()
+{
+ pid_t pid;
+
+ D_PRINTF("Starte initialen starter");
+
+ /* leave cinit alone */
+ pid = fork();
+
+ if(pid == -1) { /* err */
+ perror("fork failed\n");
+ return RT_PAR_FAIL;
+ } else if(pid == 0) { /* child */
+ /* close fifo */
+ close(f_in); close(f_out);
+
+ /* open the other way round */
+ f_in = open(CINIT_DIR SLASH F_OUT, O_RDWR);
+ f_out = open(CINIT_DIR SLASH F_IN, O_RDWR);
+ if(f_in == -1 || f_out == -1) cerr("opening fifo failed\n",RT_CHLD_FAIL);
+
+ /* open stderr, stdin, stdout to files? */
+ if ( run_svc(CINIT_INIT) == RT_CHLD_OK)
+ _exit(EX_OK);
+ else
+ _exit(EX_FAIL);
+ } else
+ return RT_PAR_OK;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c00 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c00
new file mode 100644
index 00000000..ff3bb989
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c00
@@ -0,0 +1,140 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* Run a service */
+/* We _MUST_ return!!! */
+int run_svc(char *rpath)
+{
+ int tmp, sid;
+ char abspath[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ struct stat buf;
+ struct sockaddr_un addr;
+
+ D_PRINTF("starte run_svc");
+ D_PRINTF(rpath);
+
+ /******************* begin socket *********************/
+ close(sock); /* close old socket connection, we are a fork()! */
+
+ sock = socket(PF_UNIX,SOCK_STREAM,0);
+ if( sock == -1 ) {
+ perror("socket");
+ return 0;
+ }
+ tmp = sizeof(addr);
+ memset(&addr,0,tmp);
+ strcpy(addr.sun_path, CINIT_SOCK);
+ addr.sun_family = AF_UNIX;
+
+ /* FIXME: why do we need tmp????? ... tmp == 1 is wrong!*/
+/* tmp = 1;
+ if(setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) == -1) {
+ perror("passcred");
+ return 0;
+ } */
+
+ if(connect(sock,(struct sockaddr *)&addr,tmp) == -1) {
+ perror("connect");
+ return 0;
+ }
+
+ /******************* absolute PATH ***************/
+ /* get current working dir */
+ if(! (int) getcwd(pathtmp,PATH_MAX)) {
+ perror("getcwd");
+ return 0;
+ }
+
+ /* change to rpath */
+ if(chdir(rpath) == -1) {
+ perror("chdir");
+ return 0;
+ }
+
+ /* get absolute name of rpath */
+ if(! (int) getcwd(abspath,PATH_MAX)) {
+ perror("getcwd2");
+ return 0;
+ }
+
+ /* change back */
+ if(chdir(pathtmp) == -1) {
+ perror("chdir2");
+ return 0;
+ }
+
+ /******************* REGISTER SERVICE ***************/
+ D_PRINTF(abspath);
+ tmp = msg_start_svc(abspath); /* mark us as temporary */
+ if(tmp == -1) return 1; /* already started */
+
+ /******************* BEGIN DEPENDENCIES ***************/
+ D_PRINTF("Starte needs");
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_NEEDS);
+ if( ! run_run_svcs(pathtmp) ) {
+ D_PRINTF("some NEEDED services failed)");
+ return 0;
+ }
+
+ D_PRINTF("Starte wants");
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_WANTS);
+ run_run_svcs(pathtmp); /* don't care about what happens with the want svc */
+
+ /******************* execute services ***************/
+ strcpy(pathtmp,abspath);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN);
+
+ tmp = ST_ONCE;
+ sid = 20;
+ D_PRINTF("Melde status");
+ if(!do_change_status(abspath,&tmp,&sid,sock,ACT_WRITE)) {
+ D_PRINTF("Status nicht gemeldet :(((((((((((");
+ return 0;
+ }
+ D_PRINTF("Status abgesetzt");
+
+/* if( stat(pathtmp,&buf) == 0) {
+ D_PRINTF("Respawn, ja das werden wir tun");
+ if(respawn_svc(abspath)) {
+ msg_change_status(sid,ST_RESPAWN);
+ } else {
+ D_PRINTF("error in respawn");
+ msg_change_status(sid,ST_FAIL);
+ }
+ } else {
+ D_PRINTF("einmal ausfuehren");
+ if(exec_svc(abspath)) {
+ msg_change_status(sid,ST_ONCE);
+ } else {
+ D_PRINTF("error einmalig");
+ msg_change_status(sid,ST_FAIL);
+ }
+ } */
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c01 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c01
new file mode 100644
index 00000000..e7457af0
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c01
@@ -0,0 +1,292 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets relative path */
+int run_svc_new(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt;
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+
+ /* perhaps move this code to cinit-static, so it's constant */
+ while(tmp < svc_list.process) {
+ printf("%d\n",tmp);
+
+ if( ! strcmp(rpath,svc_list.svca[tmp].abs_path) ) {
+ printf("Service im Array\n");
+ return 0;
+ }
+ tmp++;
+ }
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ return 0;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ return 0;
+ }
+
+ /* check for respawn? */
+
+ /* fork before chdir */
+ pid = fork();
+
+ if(pid == -1) {
+ printf("ERORERER\n");
+ return 0;
+ } else if(pid > 0) { /* parent gets child's PID */
+
+ /* NOT IF RESPAWN */
+ if(!respawn) {
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ return RT_PAR_OK;
+ else
+ return RT_PAR_FAIL;
+ } /* else */ /* Was tun, wenn respawn? nochmal forken als beobachter,
+ oder signal? */
+ }
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ /* THis saVES US THE OTHER STRCMP!!!!! */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check, whether we should respawn fixme: much earlier! */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( !stat(pathtmp,&buf) ) respawn = 1;
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if run is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether _one_ service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+ /* check if already running / ran / currently starting */
+
+ /* debug */
+ getcwd(pathbuf,1024);
+
+ printf("dir: %s\n",pathbuf);
+
+ /* check for service dir */
+ if( stat(path,&buf) ) {
+ printf("no such service: %s\n", path);
+ return 1;
+ }
+
+ /* check for needs -> forked() */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathbuf);
+ tmp = fork();
+ if(tmp == -1) {
+ printf("error ...\n");
+ exit(1);
+ } else if(tmp == 0) { /* child */
+ printf("child for run_run_svcs()\n");
+ run_run_svcs(pathbuf);
+ _exit(0);
+ printf("ZOOOMBIE\n");
+ }
+ else
+ printf("parent\n");
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathbuf);
+ run_run_svcs(pathbuf);
+ }
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ printf("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c02 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c02
new file mode 100644
index 00000000..7fb329b6
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c02
@@ -0,0 +1,282 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets relative path */
+int run_svc_new(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt;
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+
+ /* perhaps move this code to cinit-static, so it's constant */
+ while(tmp < svc_list.process) {
+ printf("%d\n",tmp);
+
+ if( ! strcmp(rpath,svc_list.svca[tmp].abs_path) ) {
+ printf("Service im Array\n");
+ return 0;
+ }
+ tmp++;
+ }
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ return 0;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ return 0;
+ }
+
+ /* check for respawn? */
+
+ /* fork before chdir */
+ pid = fork();
+
+ if(pid == -1) {
+ printf("ERORERER\n");
+ return 0;
+ } else if(pid > 0) { /* parent gets child's PID */
+
+ /* NOT IF RESPAWN */
+ if(!respawn) {
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ return RT_PAR_OK;
+ else
+ return RT_PAR_FAIL;
+ } /* else */ /* Was tun, wenn respawn? nochmal forken als beobachter,
+ oder signal? */
+ }
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ /* THis saVES US THE OTHER STRCMP!!!!! */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check, whether we should respawn fixme: much earlier! */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( !stat(pathtmp,&buf) ) respawn = 1;
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if run is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
+
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether the service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+
+ /* check for needs -> forked() */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathbuf);
+ tmp = fork();
+ if(tmp == -1) {
+ printf("error ...\n");
+ exit(1);
+ } else if(tmp == 0) { /* child */
+ printf("child for run_run_svcs()\n");
+ run_run_svcs(pathbuf);
+ _exit(0);
+ printf("ZOOOMBIE\n");
+ }
+ else
+ printf("parent\n");
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathbuf);
+ run_run_svcs(pathbuf);
+ }
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ printf("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c03 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c03
new file mode 100644
index 00000000..9422a7c9
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c03
@@ -0,0 +1,283 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets relative path */
+int run_svc_new(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt, sid;
+ int p_in[2], p_out[2];
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+
+ /* check if service is already (beeing) started */
+ if ( (tmp = chk_svc(rpath) ) != ST_NO) return tmp;
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ return 0;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ return 0;
+ }
+
+ /* get our own service ID */
+ sid = add_mod_svc(rpath,ST_TMP);
+
+ /* create communication pipe */
+ if ( pipe(p_in) == -1 || pipe(p_out) == -1 )
+ cerr("pipe failed",RT_PAR_FAIL);
+
+ /* check for respawn? yes, sometime... */
+
+ /* check for needs -> forked() */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathbuf);
+ tmp = fork();
+ if(tmp == -1) {
+ printf("error ...\n");
+ exit(1);
+ } else if(tmp == 0) { /* child */
+ printf("child for run_run_svcs()\n");
+ run_run_svcs(pathbuf);
+ _exit(0);
+ printf("ZOOOMBIE\n");
+ }
+ else
+ printf("parent\n");
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathbuf);
+ run_run_svcs(pathbuf);
+ }
+
+ /* fork before chdir */
+ pid = fork();
+
+ if(pid == -1) {
+ printf("ERORERER\n");
+ return 0;
+ } else if(pid > 0) { /* parent gets child's PID */
+
+ /* NOT IF RESPAWN */
+ if(!respawn) {
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ return RT_PAR_OK;
+ else
+ return RT_PAR_FAIL;
+ } /* else */ /* Was tun, wenn respawn? nochmal forken als beobachter,
+ oder signal? */
+ }
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ /* THis saVES US THE OTHER STRCMP!!!!! */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check, whether we should respawn fixme: much earlier! */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( !stat(pathtmp,&buf) ) respawn = 1;
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if run is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
+
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether the service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+beof
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ printf("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c04 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c04
new file mode 100644
index 00000000..727aa71f
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c04
@@ -0,0 +1,297 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets relative path */
+int run_svc_new(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt, sid;
+ int p_com[2];
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+
+ /* check if service is already (beeing) started */
+ if ( (tmp = chk_svc(rpath) ) != ST_NO) return tmp;
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ return 0;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ return 0;
+ }
+
+ /* get our own service ID */
+ sid = add_mod_svc(rpath,ST_TMP);
+
+ /* check, whether we should respawn */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( stat(pathtmp,&buf) == 0) respawn = 1;
+
+
+ /* if respawn, we have to create a pipe to talk with child */
+ if(respawn) {
+ if ( pipe(p_com) == -1 )
+ cerr("pipe failed",RT_PAR_FAIL);
+ }
+
+ /* fork at the beginning and before chdir */
+ pid = fork();
+
+ if( pid == -1 ) cerr("fork failed",RT_PAR_FAIL);
+
+ if(pid == -1) {
+ cerr("fork failed\n", RT_PAR_FAIL);
+ } else if(pid > 0) { /* parent gets child's PID */
+
+ if(respawn) {
+ /* read the final byte from child */
+ read(p_com[0],&tmp,1); /* FIXME: check return */
+ if(tmp == ST_RESPAWN) {
+ printf("kind sagte, wir respawnenen jetzt\n");
+ add_mod_svc(rpath,ST_RESPAWN); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else { /* child failed */
+ printf("kind sagte, respawn kaputt\n");
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ }
+ } else { /* execute once */
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status)) {
+ add_mod_svc(rpath,ST_ONCE); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else {
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ }
+ }
+
+ /* done till here. PARENTS EXECUTION ENDED! */
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+
+ /* check for needs */
+
+ /* do we need absolute paths anymore? */
+ // strcpy(pathbuf,rpath);
+ // strcat(pathbuf,"/");
+ strcat(pathtmp,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathbuf);
+ pid = fork();
+ if(tmp == -1) {
+ cerr("error ...\n", RT_PAR_FAIL);
+ } else if(tmp == 0) {
+ printf("child for run_run_svcs()\n");
+ run_run_svcs(pathbuf);
+ _exit(0);
+ }
+ else
+ printf("parent\n");
+ }
+
+ /* check for wants -> forked() ? */
+ strcpy(pathbuf,rpath);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_WANTS);
+
+ if( ! stat(pathbuf,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathbuf);
+ run_run_svcs(pathbuf);
+ }
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if run is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
+
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether the service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ printf("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c05 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c05
new file mode 100644
index 00000000..927a9261
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c05
@@ -0,0 +1,294 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets relative path */
+int run_svc_new(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt, sid;
+ int p_com[2];
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+
+ /* check if service is already (beeing) started */
+ if ( (tmp = chk_svc(rpath) ) != ST_NO) return tmp;
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ return 0;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ return 0;
+ }
+
+ /* get our own service ID */
+ sid = add_mod_svc(rpath,ST_TMP);
+
+ /* check, whether we should respawn */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( stat(pathtmp,&buf) == 0) respawn = 1;
+
+
+ /* if respawn, we have to create a pipe to talk with child */
+ if(respawn) {
+ if ( pipe(p_com) == -1 )
+ cerr("pipe failed",RT_PAR_FAIL);
+ }
+
+ /* fork at the beginning and before chdir */
+ pid = fork();
+
+ if( pid == -1 ) cerr("fork failed",RT_PAR_FAIL);
+
+ if(pid == -1) {
+ cerr("fork failed\n", RT_PAR_FAIL);
+ } else if(pid > 0) { /* parent gets child's PID */
+
+ if(respawn) {
+ /* read the final byte from child */
+ read(p_com[0],&tmp,1); /* FIXME: check return */
+ if(tmp == ST_RESPAWN) {
+ printf("kind sagte, wir respawnenen jetzt\n");
+ add_mod_svc(rpath,ST_RESPAWN); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else { /* child failed */
+ printf("kind sagte, respawn kaputt\n");
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ }
+ } else { /* execute once */
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status)) {
+ add_mod_svc(rpath,ST_ONCE); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else {
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ }
+ }
+
+ /* done till here. PARENTS EXECUTION ENDED! */
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check for needs */
+
+ /* CHECKME: do we need absolute paths anymore? */
+ // strcpy(pathbuf,rpath);
+ // strcat(pathbuf,"/");
+ strcpy(pathtmp,C_NEEDS);
+ if( ! stat(pathbuf,&buf) ) {
+ printf("going for %s\n",pathtmp);
+ if( run_run_svcs(pathtmp) != RT_ALL_STARTED ) {
+ cerr("couldn't start all services I depend on\n",RT_CHLD_FAIL);
+ }
+ }
+
+ /* check for wants -> forked() ? */
+// strcpy(pathbuf,rpath);
+// strcat(pathbuf,"/");
+ strcpy(pathtmp,C_WANTS);
+
+ if( ! stat(pathtmp,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathtmp);
+ run_run_svcs(pathtmp); /* don't care if everything went well */
+ }
+
+ /* everything is started, now start ourselves! */
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+// strcpy(pathtmp,pathbuf);
+// strcat(pathtmp,"/");
+// strcpy(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if "./run" is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+
+ /* STOPPPPPPPED **********
+ broken code: malloc of char* missing! */
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
+
+
+/***********************************************************************
+ * run_svc: gets a wants/needs directory
+ * returns whether the service failed or not
+ */
+int run_svc(char *path)
+{
+ DIR *d_tmp = NULL;
+ struct dirent *tdirent;
+ char *p, pathbuf[1024];
+ struct stat buf;
+ int tmp;
+
+ /* check for service/run */
+ strcpy(pathbuf,path);
+ strcat(pathbuf,"/");
+ strcat(pathbuf,C_RUN);
+
+ d_tmp = opendir(pathbuf);
+
+ if(d_tmp == NULL) {
+ printf("failed to open dir...");
+ return 0;
+ }
+
+ while( (tdirent = readdir(d_tmp) ) != NULL) {
+ if (strcmp(tdirent->d_name, ".") == 0 || strcmp(tdirent->d_name, "..") == 0)
+ continue;
+
+ p=tdirent->d_name;
+ while(*p != '\0') {
+ write(1,p,1);
+ p++;
+ }
+ write(1,"\n",1);
+ }
+
+ closedir(d_tmp);
+
+ return 1;
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c05.2 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c05.2
new file mode 100644
index 00000000..90d94b65
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c05.2
@@ -0,0 +1,320 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* Run a service */
+/* We _MUST_ return!!! */
+int run_svc(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt, sid;
+ int p_com[2]; /* talk to respawnig watcher */
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+ struct sockaddr_un addr;
+
+ D_PRINTF("starte run_svc");
+ D_PRINTF(rpath);
+
+ /******************* begin socket *********************/
+ /* close old socket connection */
+ D_PRINTF("beginne socket zeugs");
+ close(sock);
+
+ sock = socket(PF_UNIX,SOCK_STREAM,0);
+ if( sock == -1 ) {
+ perror("socket");
+ return 0;
+ }
+ memset(&addr,0,sizeof(addr));
+ strcpy(addr.sun_path, CINIT_SOCK);
+
+ addr.sun_family = AF_UNIX;
+ tmp = sizeof(addr);
+
+ if(setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) == -1) {
+ perror("passcred");
+ return 0;
+ }
+ if(connect(sock,(struct sockaddr *)&addr,tmp) == -1) {
+ perror("connect");
+ return 0;
+ }
+
+ /******************* end socket *********************/
+
+ sid = msg_start_svc(rpath); /* now we are temporary */
+ if(sid == -1) {
+ cerr("cinit returned start error",RT_CHLD_FAIL);
+ return 0;
+ }
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ msg_change_status(sid,ST_FAIL);
+ return 0;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ msg_change_status(sid,ST_FAIL);
+ return 0;
+ }
+
+ /* check, whether we should respawn */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( stat(pathtmp,&buf) == 0) {
+ D_PRINTF("Respawn, ja das werden wir tun");
+ respawn = 1;
+ }
+
+ /* if respawn, we have to create a pipe to talk with child */
+ if(respawn) {
+ if ( pipe(p_com) == -1 ) {
+ perror("pipe");
+ cerr("pipe failed",RT_PAR_FAIL);
+ }
+ }
+
+ /* clone */
+ pid = fork();
+ if( pid == -1 ) {
+ perror("fork");
+ cerr("fork failed",RT_CHLD_FAIL);
+ return 0;
+ }
+
+ _exit(0);
+
+ /* the following block handles parent situation */
+
+ if(pid > 0) { /* parent gets child's PID */
+
+ /*************** THIS BLOCK IS CRAP ******************/
+
+ /* FIXME: when respawing, we'll watch our child */
+ if(respawn) {
+ tmp = MSG_FAIL;
+ read(p_com[0],&tmp,1); /* FIXME: check return */
+ if(tmp == MSG_OK) {
+ D_PRINTF("kind sagte, wir respawnenen jetzt\n");
+ msg_change_status(sid,ST_RESPAWN); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else { /* child failed */
+ printf("kind sagte, respawn kaputt\n");
+ msg_change_status(sid,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ /* FIXME: MISSING:
+ - signal handling (stop respawing)
+ - waitpid() in while(1)
+ */
+ _exit(0); /* FIXME !!! */
+
+ /*************** END THIS BLOCK IS CRAP ******************/
+
+ } else /* don't RESPAWN */ { /* execute only once */
+ D_PRINTF("Warte EINMAL auf mein Kind...");
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status)) {
+ add_mod_svc(rpath,ST_ONCE); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else {
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ }
+ }
+ /* done till here. PARENTS EXECUTION ENDED! */
+
+
+ /*********** CHILD EXECUTION HERE ***********/
+ do {
+
+
+ } while(respawn);
+
+
+
+ /* change to service dir */
+ if( chdir(rpath) == -1) {
+ /* FIXME: errno! */
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check for needs */
+
+ /* CHECKME: do we need absolute paths anymore? */
+ // strcpy(pathbuf,rpath);
+ // strcat(pathbuf,"/");
+ strcpy(pathtmp,C_NEEDS);
+ if( ! stat(pathtmp,&buf) ) {
+ printf("going for %s\n",pathtmp);
+ if( run_run_svcs(pathtmp) != RT_ALL_STARTED ) {
+ cerr("couldn't start all services I depend on\n",RT_CHLD_FAIL);
+ }
+ }
+
+ /* check for wants -> forked() ? */
+// strcpy(pathbuf,rpath);
+// strcat(pathbuf,"/");
+ strcpy(pathtmp,C_WANTS);
+
+ if( ! stat(pathtmp,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathtmp);
+ run_run_svcs(pathtmp); /* don't care if everything went well */
+ }
+
+ /* everything is started, now start ourselves! */
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+// strcpy(pathtmp,pathbuf);
+// strcat(pathtmp,"/");
+// strcpy(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if "./run" is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+
+ /* STOPPPPPPPED **********
+ broken code: malloc of char* missing! */
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c06 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c06
new file mode 100644
index 00000000..7dd265fc
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c06
@@ -0,0 +1,293 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets (relative or absolute) path */
+int run_svc(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt, sid;
+ int p_com[2];
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+ struct sockaddr_un addr;
+
+
+ D_PRINTF("starte run_svc");
+ D_PRINTF(rpath);
+
+ /******************* begin socket *********************/
+ /* close old socket connection */
+ D_PRINTF("beginne socket zeugs");
+ close(sock);
+
+ sock = socket(PF_UNIX,SOCK_STREAM,0);
+ if( sock == -1 ) {
+ perror("Fehler");
+ _exit(1);
+ }
+ memset(&addr,0,sizeof(addr));
+ strcpy(addr.sun_path, CINIT_SOCK);
+
+ addr.sun_family = AF_UNIX;
+ tmp = sizeof(addr);
+
+ if(setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) == -1) {
+ perror("passcred");
+ cerr("Does your OS not support SO_PASSCRED (man 7 socket)?",RT_PAR_FAIL);
+ }
+
+ if(connect(sock,(struct sockaddr *)&addr,tmp) == -1) {
+ perror("connect");
+ _exit(1);
+ }
+
+ /******************* end socket *********************/
+
+ msg_start_svc(rpath);
+ D_PRINTF("in runsvc");
+ _exit(0);
+
+ /* check if service is already (beeing) started */
+ if ( (tmp = chk_svc_client(rpath) ) != ST_NO) return tmp;
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ return ;
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ return 0;
+ }
+
+ /* get our own service ID */
+ sid = add_mod_svc(rpath,ST_TMP);
+
+ /* check, whether we should respawn */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( stat(pathtmp,&buf) == 0) respawn = 1;
+
+
+ /* if respawn, we have to create a pipe to talk with child */
+ if(respawn) {
+ if ( pipe(p_com) == -1 )
+ cerr("pipe failed",RT_PAR_FAIL);
+ }
+
+ /* fork at the beginning and before chdir */
+ pid = fork();
+
+ /* FIXME: pay attention: we are possibly also a fork()! */
+
+ if( pid == -1 ) cerr("fork failed",RT_PAR_FAIL);
+
+ if(pid > 0) { /* parent gets child's PID */
+ if(respawn) {
+ /* read the final byte from child */
+ read(p_com[0],&tmp,1); /* FIXME: check return */
+ if(tmp == ST_RESPAWN) {
+ D_PRINTF("kind sagte, wir respawnenen jetzt\n");
+ add_mod_svc(rpath,ST_RESPAWN); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else { /* child failed */
+ printf("kind sagte, respawn kaputt\n");
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ } else { /* execute once */
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status)) {
+ add_mod_svc(rpath,ST_ONCE); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else {
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ }
+ }
+ /* done till here. PARENTS EXECUTION ENDED! */
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check for needs */
+
+ /* CHECKME: do we need absolute paths anymore? */
+ // strcpy(pathbuf,rpath);
+ // strcat(pathbuf,"/");
+ strcpy(pathtmp,C_NEEDS);
+ if( ! stat(pathtmp,&buf) ) {
+ printf("going for %s\n",pathtmp);
+ if( run_run_svcs(pathtmp) != RT_ALL_STARTED ) {
+ cerr("couldn't start all services I depend on\n",RT_CHLD_FAIL);
+ }
+ }
+
+ /* check for wants -> forked() ? */
+// strcpy(pathbuf,rpath);
+// strcat(pathbuf,"/");
+ strcpy(pathtmp,C_WANTS);
+
+ if( ! stat(pathtmp,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathtmp);
+ run_run_svcs(pathtmp); /* don't care if everything went well */
+ }
+
+ /* everything is started, now start ourselves! */
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+// strcpy(pathtmp,pathbuf);
+// strcat(pathtmp,"/");
+// strcpy(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if "./run" is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+
+ /* STOPPPPPPPED **********
+ broken code: malloc of char* missing! */
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c07 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c07
new file mode 100644
index 00000000..e62eff54
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c07
@@ -0,0 +1,304 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "cinit.h"
+
+/* run a service, gets (relative or absolute) path */
+int run_svc(char *rpath)
+{
+ int tmp=0, respawn = 0, status, fd, cnt, sid;
+ int p_com[2]; /* talk to respawnig watcher */
+ char pathbuf[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
+ char **nargv, *sbuf, *p; /* the argv for the executed process */
+ struct stat buf;
+ pid_t pid;
+ struct sockaddr_un addr;
+
+
+ D_PRINTF("starte run_svc");
+ D_PRINTF(rpath);
+
+ /******************* begin socket *********************/
+ /* close old socket connection */
+ D_PRINTF("beginne socket zeugs");
+ close(sock);
+
+ sock = socket(PF_UNIX,SOCK_STREAM,0);
+ if( sock == -1 ) {
+ perror("socket");
+ _exit(1);
+ }
+ memset(&addr,0,sizeof(addr));
+ strcpy(addr.sun_path, CINIT_SOCK);
+
+ addr.sun_family = AF_UNIX;
+ tmp = sizeof(addr);
+
+ if(setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) == -1) {
+ perror("passcred");
+ cerr("Does your OS not support SO_PASSCRED (man 7 socket)?",RT_PAR_FAIL);
+ }
+
+ if(connect(sock,(struct sockaddr *)&addr,tmp) == -1) {
+ perror("connect");
+ _exit(1);
+ }
+
+ /******************* end socket *********************/
+
+ /* check whether service exists */
+ if( stat(rpath,&buf) ) {
+ printf("Service does not exist %s\n",rpath);
+ _exit(1);
+ } else if( ! S_ISDIR(buf.st_mode) ) {
+ printf("Service is not a dir (%s)!\n",rpath);
+ _exit(1);
+ }
+
+ tmp = msg_start_svc(rpath); /* now we are temporary */
+
+ D_PRINTF("in runsvc");
+
+ if(tmp == -1) {
+ cerr("cinit returned start error",RT_CHLD_FAIL);
+ _exit(1);
+ }
+
+ /* check, whether we should respawn */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RESPAWN); /* FIXME: check return values */
+ if( stat(pathtmp,&buf) == 0) {
+ D_PRINTF("Respawn, ja das werden wir tun");
+ respawn = 1;
+ }
+
+ /* if respawn, we have to create a pipe to talk with child */
+ if(respawn) {
+ if ( pipe(p_com) == -1 ) {
+ perror("pipe");
+ cerr("pipe failed",RT_PAR_FAIL);
+ }
+ }
+
+ pid = fork();
+ /* pay attention: we are also a fork()! */
+ if( pid == -1 ) {
+ perror("fork");
+ cerr("fork failed",RT_CHLD_FAIL);
+ _exit(1);
+ }
+
+ _exit(0);
+
+ /* the following block handles parent situation */
+
+ if(pid > 0) { /* parent gets child's PID */
+
+ /* FIXME: when respawing, we'll watch our child */
+ if(respawn) {
+ tmp = MSG_FAIL;
+ read(p_com[0],&tmp,1); /* FIXME: check return */
+ if(tmp == MSG_OK) {
+ D_PRINTF("kind sagte, wir respawnenen jetzt\n");
+ add_mod_svc(rpath,ST_RESPAWN); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else { /* child failed */
+ printf("kind sagte, respawn kaputt\n");
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ } else /* don't RESPAWN */ { /* execute only once */
+ D_PRINTF("Warte EINMAL auf mein Kind...");
+ waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status)) {
+ add_mod_svc(rpath,ST_ONCE); /* FIXME: search bei sid! */
+ return RT_PAR_OK;
+ } else {
+ add_mod_svc(rpath,ST_FAIL); /* FIXME: search bei sid! */
+ return RT_PAR_FAIL;
+ }
+ }
+ }
+ /* done till here. PARENTS EXECUTION ENDED! */
+
+ /*********** CHILD EXECUTION HERE ***********/
+
+ /* change to service dir */
+ if( chdir(rpath) == -1) {
+ printf("chdir(%s) failed!\n",rpath);
+ return 1;
+ }
+
+ /* getcwd returns the full service name */
+ if(getcwd(pathbuf,PATH_MAX) == NULL) return 0;
+
+ printf("absolut and current %s\n",pathbuf);
+
+ /* check for needs */
+
+ /* CHECKME: do we need absolute paths anymore? */
+ // strcpy(pathbuf,rpath);
+ // strcat(pathbuf,"/");
+ strcpy(pathtmp,C_NEEDS);
+ if( ! stat(pathtmp,&buf) ) {
+ printf("going for %s\n",pathtmp);
+ if( run_run_svcs(pathtmp) != RT_ALL_STARTED ) {
+ cerr("couldn't start all services I depend on\n",RT_CHLD_FAIL);
+ }
+ }
+
+ /* check for wants -> forked() ? */
+// strcpy(pathbuf,rpath);
+// strcat(pathbuf,"/");
+ strcpy(pathtmp,C_WANTS);
+
+ if( ! stat(pathtmp,&buf) ) {
+ printf("dir gibt es auch: %s\n", pathtmp);
+ run_run_svcs(pathtmp); /* don't care if everything went well */
+ }
+
+ /* everything is started, now start ourselves! */
+
+ /**** RETRIEVE REAL BINARY NAME ****/
+ /* .../run */
+// strcpy(pathtmp,pathbuf);
+// strcat(pathtmp,"/");
+// strcpy(pathtmp,C_RUN); /* FIXME: check return values */
+
+ /* readlink retrieves real name, if "./run" is a symlink */
+ if ( (tmp = readlink(C_RUN,pathtmp,PATH_MAX) ) == -1) {
+ if (errno != EINVAL) cerr("readlinx failed\n",RT_CHLD_FAIL);
+
+ /* binary is not a link, copy that to argv0 */
+ sbuf = (char *) malloc( strlen(pathbuf) + strlen(C_RUN) + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strcpy(sbuf,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN); /* FIXME: check return values */
+
+ } else { /* it's a link, copy to sbuf */
+ sbuf = (char *) malloc( tmp + 1 );
+ if(sbuf == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ strncpy(sbuf,pathtmp,tmp);
+ sbuf[tmp] = '\0';
+ }
+ printf("argv0: %s\n",sbuf);
+
+ /**** BUILD ARGV ****/
+
+ /* STOPPPPPPPED **********
+ broken code: malloc of char* missing! */
+ nargv = malloc( sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[0] = sbuf;
+
+ /**** read params ****/
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_PARAMS);
+ if( !stat(pathtmp,&buf) ) {
+ fd = open(pathtmp,O_RDONLY);
+ if(fd == -1) cerr("open params failed\n",RT_CHLD_FAIL);
+
+ sbuf = NULL;
+ cnt = 0;
+ /* most likely one round */
+ while ( (tmp = read(fd,pathtmp,PATH_MAX-1) ) != 0 ) {
+ if(tmp == -1) cerr("read params failed\n",RT_CHLD_FAIL);
+
+ /* STRCHR >> tmp ???? */
+ /* terminate for strchr - do we really need that? */
+ pathtmp[PATH_MAX-1] = '\0';
+
+ sbuf = realloc(sbuf,cnt + tmp + 1);
+ if(sbuf == NULL) cerr("realloc failed\n",RT_CHLD_FAIL);
+
+ /* copy to temporary buffer */
+ strncpy(&sbuf[cnt],pathtmp,tmp);
+
+ cnt += tmp;
+ printf("Groesse: %d (%d)\n",tmp,cnt+1);
+ }
+ close(fd);
+ } /* if params */
+ sbuf[cnt] = '\0';
+
+ /* build argv, now really */
+ /* use the allocated buffer and replace \n with \0 ;-) */
+
+ cnt = 1;
+// p = sbuf;
+ while ( *sbuf != '\0' ) {
+ p = strchr(sbuf,'\n'); /* set p to next \n */
+
+ nargv = realloc(nargv,(cnt+1) * sizeof(char *) );
+ if(nargv == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+// nargv[cnt] = malloc( sizeof(char *) );
+// if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = sbuf; /* beginning of argv[cnt] */
+ *p = '\0'; /* end argv[cnt] */
+
+ tmp = p - sbuf;
+ printf("argv[%d]: %s (%d)\n",cnt,nargv[cnt],tmp);
+ sbuf = p+1;
+ cnt++;
+ }
+ /* GNAAAAAAAAAA: correct???? */
+ /* close argv list */
+ nargv[cnt] = malloc( sizeof(char *) );
+ if(nargv[cnt] == NULL) cerr("malloc failed\n",RT_CHLD_FAIL);
+
+ nargv[cnt] = NULL;
+
+ // char *strchr(const char *s, int c);
+ /* end buffer */
+
+ /* get size of argv[n] */
+
+ /* run the fscking service */
+ strcpy(pathtmp,pathbuf);
+ strcat(pathtmp,"/");
+ strcat(pathtmp,C_RUN);
+ printf("Service starten: %s \n", pathtmp);
+
+ /* nothing to run, so it's finished */
+ if( stat(pathtmp,&buf) ) _exit(0);
+
+ //execl(pathtmp,pathtmp,"/bin/ls","-l", "/bin/echo");
+ execv(pathtmp,nargv);
+
+// _exit(1);
+
+/*
+ if(respawn)
+ tmp = 0;
+ execl();
+ return 1;
+*/
+}
diff --git a/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c08 b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c08
new file mode 100644
index 00000000..587e13e2
--- /dev/null
+++ b/software/cinit/browse_source/cinit-0.0.4/old/run_svc.c08
@@ -0,0 +1,316 @@
+/*
+ * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
+ * run_svc
+ * part of cinit
+ */
+
+#include
+#include
+#include
+#include
+#include