* renamed libkernel::port to libkernel::message_port
[lightOS.git] / server / init / init.cpp
blob63854a872954e2080d39d743611c5df271735f77
1 /*
2 lightOS application
3 Copyright (C) 2006-2008 Jörg Pfähler
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <algorithm>
20 #include <iterator>
21 #include <iostream>
22 #include <lightOS/config.hpp>
23 #include <lightOS/lightOS.hpp>
24 #include <lightOS/server.hpp>
25 using namespace lightOS;
26 using namespace std;
28 using libkernel::message;
30 processId execute_file(const string &cmd, size_t flags)
32 string::const_iterator firstspace = find<string::iterator>(cmd.begin(), cmd.end(), ' ');
33 string name; // TODO ("gzip://");
34 string tmp(cmd.begin(), firstspace);
35 name.append(tmp);
37 file File(name.c_str(), access::read);
38 if (!File)
39 return 0;
40 size_t size = File.blocksize() * File.blockcount();
41 if (size == 0)
42 return 0;
44 libkernel::shared_memory shm = File.read(0, size);
45 if (shm.size() != size)
46 return 0;
48 // HACK: This is actually not a good idea, but who cares? *g*
49 char libraryName[1000];
50 libraryName[0] = '\0';
51 processId result;
52 while( (result = execute(shm.address<void>(), size, cmd.c_str(), flags, libraryName)) == 0 &&
53 strlen(libraryName) != 0)
55 cout << "init: loading library \"" << libraryName << "\"" << endl;
56 if (execute_file(libraryName, 0) == 0)
58 cerr << "init: library \"" << libraryName << "\" not found" << endl;
59 return 0;
61 libraryName[0] = '\0';
63 return result;
66 bool do_boot_config(const config::section<config::key_only> &section)
68 for (size_t i = 0;i < section.entity_count();i++)
70 if (section[i].is_section() == true)
71 do_boot_config(*static_cast<const config::section<config::key_only>*>(&section[i]));
72 else
74 const config::key_only *entity = static_cast<const config::key_only*>(&section[i]);
75 cout << "init: " << entity->name() << endl;
76 bool bServer = false;
77 if (section.name() == "server")bServer = true;
78 if (execute_file(entity->name(), bServer ? process::server : 0) == 0)
79 return false;
82 return true;
85 bool wait_mount(port &Port,
86 const char *fs,
87 const char *mountpoint)
89 cout << "init: " << fs << " server" << endl;
90 waitForFilesystemRegistration(Port, fs);
92 if (mount(Port, mountpoint, fs) == false)
94 cerr << "init: failed" << endl;
95 return false;
97 return true;
100 int main(int argc, char *argv[])
102 port Port(libkernel::message_port::init, true);
103 if (!Port)
105 cerr << "init: init already started" << endl;
106 return -1;
109 // Wait for the console server
110 Port.wait_for_other(libkernel::message_port::console);
112 // Print the lightOS version
113 pair<size_t,size_t> version = get_kernel_version();
115 cout << "lightOS V" << dec << version.first << '.' << version.second;
116 #ifdef X86
117 cout << " x86";
118 #endif
119 #ifdef X86_64
120 cout << " x86-64";
121 #endif
122 cout << endl << endl;
124 // Find the bootdevice
125 bool bGui = false;
126 const char *bootdev = 0;
127 const char *bootfs = 0;
128 for (int i=1;i < argc;i++)
129 if (strcmp(argv[i], "--boot") == 0)
131 ++i;
132 if (i < argc)bootdev = argv[i];
134 else if (strcmp(argv[i], "--fs") == 0)
136 ++i;
137 if (i < argc)bootfs = argv[i];
139 else if (strcmp(argv[i], "--gui") == 0)bGui = true;
141 if (bootdev == 0 ||
142 bootfs == 0)
144 cerr << "init: No boot device specified" << endl;
145 return -1;
148 // Wait for vfs server
149 cout << "init: vfs server" << endl;
150 Port.wait_for_other(libkernel::message_port::vfs);
152 // Mount pseudo filesystems
153 if (wait_mount(Port, "devfs", "dev://") == false)return -1;
155 #if 0
156 if (wait_mount(Port, "gzipfs", "gzip://") == false)return -1;
157 #endif
159 // Mount boot device
160 cout << "init: mounting \"" << bootdev << "\"" << endl;
161 waitForFilesystemRegistration(Port, bootfs);
162 while (file::exists(bootdev, Port) == file::none){wait(1);}
163 if (mount(Port, "/", bootfs, bootdev) == false)
165 cerr << "init: failed" << endl;
166 return -1;
169 // Execute & Mount the remaining pseudo filesystems
170 cout << "init: pipefs" << endl;
171 if (execute_file("/system/server/pipefs", process::server) == 0)
173 cerr << "init: failed" << endl;
174 return 0;
176 cout << "init: tmpfs" << endl;
177 if (execute_file("/system/server/tmpfs", process::server) == 0)
179 cerr << "init: failed" << endl;
180 return 0;
183 // Mount the remaining pseudo filesystems
184 if (wait_mount(Port, "pipefs", "pipe://") == false)return -1;
185 if (wait_mount(Port, "tmpfs", "tmp://") == false)return -1;
187 // Parse boot.cfg
188 config::section<config::key_only> *result = config::parse<config::key_only>("/system/config/boot.cfg");
189 if (result == 0)
191 cerr << "init: No configuration file" << endl;
192 return -1;
194 if (do_boot_config(*result) == false)
196 cerr << "init: failed" << endl;
197 return -1;
201 // Execute gui
202 if (bGui == true)
204 const char *name = "/system/server/gui";
205 cout << "init: " << name << endl;
206 if (execute_file(name, process::server) == 0)
208 cerr << "init: failed" << endl;
209 return 0;
213 cout << "init: done" << endl;
215 if (bGui == false)
217 message msg(libkernel::message_port::console, libkernel::message::init_done);
218 Port.send(msg);
221 // Server
222 message msg;
223 while (Port.get(msg))
225 libkernel::shared_memory shm = msg.get_shared_memory();
226 switch (msg.type())
228 case libkernel::message::ping:
230 message reply(msg.port(), libkernel::message::pong);
231 Port.send(reply);
232 }break;
233 case libkernel::message::init_execute:
235 if (msg.attribute() == libkernel::shared_memory::transfer_ownership)
237 // TODO: security!
238 char *cmdline = shm.address<char>();
239 cmdline[shm.size()] = '\0';
240 processId pid = execute_file(cmdline, msg.param1());
241 message reply(msg.port(), libkernel::message::init_execute, pid);
242 Port.send(reply);
244 }break;
245 // TODO: Until we have a proper kernel log
246 case _LIBKERNEL_MSG_LIBOS_WARNING:
248 cerr << shm.address<char>();
253 return 0;