remove cinit source - archives are available
Signed-off-by: Nico Schottelius <nico@brief.schottelius.org>
This commit is contained in:
		
					parent
					
						
							
								b18172d939
							
						
					
				
			
			
				commit
				
					
						b8b6c0fecc
					
				
			
		
					 17791 changed files with 0 additions and 776233 deletions
				
			
		| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
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?
 | 
			
		||||
| 
						 | 
				
			
			@ -1,340 +0,0 @@
 | 
			
		|||
		    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.
 | 
			
		||||
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,213 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
  branch "info.clinux.cinit"
 | 
			
		||||
database "/home/user/nico/monotone.db"
 | 
			
		||||
     key ""
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
81778a4d16c2b27a8e686600dde41795fc5ed6b8
 | 
			
		||||
| 
						 | 
				
			
			@ -1,83 +0,0 @@
 | 
			
		|||
#
 | 
			
		||||
# 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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,92 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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<<at>>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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,66 +0,0 @@
 | 
			
		|||
- 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,41 +0,0 @@
 | 
			
		|||
#!/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."
 | 
			
		||||
| 
						 | 
				
			
			@ -1,60 +0,0 @@
 | 
			
		|||
#!/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."
 | 
			
		||||
| 
						 | 
				
			
			@ -1,43 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,40 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,129 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * cinit
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * header of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* includes */
 | 
			
		||||
#include <sys/types.h>  /* 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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
client/
 | 
			
		||||
   These sources are used by the children which are spawned by cinit.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * tell cinit that I want to start a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,41 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,246 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,104 +0,0 @@
 | 
			
		|||
KOPIE VON RUN_SVC
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,29 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * tell cinit that I want change the status of a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * tell cinit that I want to start a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,68 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,77 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * cinit
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run services parallel
 | 
			
		||||
 */
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,111 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* headers are clean */
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
comm/
 | 
			
		||||
   The communication part of cinit.
 | 
			
		||||
   The functions are used in client and in server code.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,69 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * change status of a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,32 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * write result of action
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * try to start a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
This directory contains the cinit configuration.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
.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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
halt
 | 
			
		||||
 | 
			
		||||
Name of the service we should start when 'halting' (system stop, but no
 | 
			
		||||
power off).
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
init
 | 
			
		||||
 | 
			
		||||
The name of the init service.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
needs
 | 
			
		||||
 | 
			
		||||
Name of the service sub-directory containing the needed services.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
off
 | 
			
		||||
 | 
			
		||||
Name of the file we start, when stopping the service.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
on
 | 
			
		||||
 | 
			
		||||
Name of the file we start, when starting the service.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
.params
 | 
			
		||||
 | 
			
		||||
The extension to c_on and c_off, which will contain the parameters \n seperated.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
poweroff
 | 
			
		||||
 | 
			
		||||
Name of the service we should start, when system power-off is called.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
reboot
 | 
			
		||||
 | 
			
		||||
Name of the service we should start on reboot.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
respawn
 | 
			
		||||
 | 
			
		||||
If this file exists in a service directory, cinit will respawn the service.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
coala
 | 
			
		||||
 | 
			
		||||
The name of the socket cinit will use (currently: below tmpdir, 
 | 
			
		||||
see doc/ipc.thoughts).
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
tmp
 | 
			
		||||
 | 
			
		||||
The name of the temporary directory, where we'll mount tmpfs to create the socket
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
tmpfs
 | 
			
		||||
 | 
			
		||||
The name of the filesystem to use to mount a memory filesystem.
 | 
			
		||||
On Linux this is "tmpfs".
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
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".
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
wants
 | 
			
		||||
 | 
			
		||||
Name of the service sub-directory containing the wanted services.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
/etc/cinit
 | 
			
		||||
 | 
			
		||||
This is where all configuration for cinit will be stored.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
-d
 | 
			
		||||
 | 
			
		||||
Parameter to install_prog to create directories.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
/usr/bin/install
 | 
			
		||||
 | 
			
		||||
Program we use to install. install_directory contains parameter
 | 
			
		||||
to create directory.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
/
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
5
 | 
			
		||||
 | 
			
		||||
How many seconds to sleep before respawning a failed process.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
root
 | 
			
		||||
 | 
			
		||||
The group, which should own the communication socket.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
0770
 | 
			
		||||
 | 
			
		||||
Octal mode of socket.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
32
 | 
			
		||||
 | 
			
		||||
Maximum process waiting in the socket queue. The default is much
 | 
			
		||||
more than enough.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
root
 | 
			
		||||
 | 
			
		||||
The one who should own the communication socket.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
 | 
			
		||||
-------------
 | 
			
		||||
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!
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
'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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,89 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,74 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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.
 | 
			
		||||
--------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -1,48 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,55 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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/
 | 
			
		||||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,60 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
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.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
- 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * cinit
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * print string
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,45 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * cinit.c
 | 
			
		||||
 * part of cLinux/cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#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); */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * add_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * cinit
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * print error to stderr and exist
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#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(...) 
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +0,0 @@
 | 
			
		|||
#!/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"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,105 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (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 <sys/types.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
 | 
			
		||||
/* *stat() */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,198 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (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 <sys/types.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
 | 
			
		||||
/* *stat() */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* wait() */
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
/* strlen */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,241 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (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 <sys/types.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
 | 
			
		||||
/* *stat() */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* wait() */
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
/* strlen */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,130 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * cinit.c
 | 
			
		||||
 * part of cLinux
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* *stat() */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* open */
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
/* siggnal */
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
/* PATH_MAX */
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
/* printf() */
 | 
			
		||||
//#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
/* str* */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,137 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * cinit.c
 | 
			
		||||
 * part of cLinux/cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* *stat() */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* open */
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
/* siggnal */
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
/* PATH_MAX */
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
/* printf() */
 | 
			
		||||
//#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
/* str* */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,158 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * cinit.c
 | 
			
		||||
 * part of cLinux/cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* *stat() */
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* open */
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
/* siggnal */
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
/* PATH_MAX */
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
/* printf() */
 | 
			
		||||
//#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
/* str* */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* sockets */
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#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) ;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,85 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
#!/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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,80 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * cinit
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * header of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* includes */
 | 
			
		||||
#include <sys/types.h>  /* 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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (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); 
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,65 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * change status of a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,121 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
/etc/cinit
 | 
			
		||||
   -> init/
 | 
			
		||||
   -> shutdown/
 | 
			
		||||
   -> reboot/
 | 
			
		||||
 | 
			
		||||
<service>
 | 
			
		||||
   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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,200 +0,0 @@
 | 
			
		|||
--------------------------------------------------------------------------------
 | 
			
		||||
/etc/cinit
 | 
			
		||||
   -> init/
 | 
			
		||||
   -> shutdown/
 | 
			
		||||
   -> reboot/
 | 
			
		||||
 | 
			
		||||
<service>
 | 
			
		||||
   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?
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * change status of a service
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,23 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * cinit
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * tell cinit we start a service
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* 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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,100 +0,0 @@
 | 
			
		|||
/* 
 | 
			
		||||
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
			
		||||
 * run_svc
 | 
			
		||||
 * part of cinit
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue