xref: /haiku/src/tests/servers/registrar/run_test_registrar.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
1 /*
2  * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 
11 #include <OS.h>
12 #include <image.h>
13 #include <Entry.h>
14 #include <Query.h>
15 #include <Path.h>
16 #include <String.h>
17 #include <Volume.h>
18 #include <fs_info.h>
19 
20 
21 extern const char* __progname;
22 
23 
24 static status_t
25 launch_registrar(const char* registrarPath)
26 {
27 	const char* args[] = { registrarPath, NULL };
28 	thread_id thread = load_image(1, args, (const char**)environ);
29 	if (thread < B_OK) {
30 		fprintf(stderr, "%s: Could not start the registrar: %s\n",
31 			__progname, strerror(thread));
32 		return (status_t)thread;
33 	}
34 
35 	return resume_thread(thread);
36 }
37 
38 
39 int
40 main(int argc, char* argv[])
41 {
42 	team_info teamInfo;
43 	int32 cookie = 0;
44 	while (get_next_team_info(&cookie, &teamInfo) == B_OK) {
45 		if (!strncmp(teamInfo.args, "/boot/beos/", 11)
46 			|| !strncmp(teamInfo.args, "/boot/system/", 13)) {
47 			// this is a system component and not worth to investigate
48 			continue;
49 		}
50 
51 		thread_info threadInfo;
52 		int32 threadCookie = 0;
53 		while (get_next_thread_info(teamInfo.team, &threadCookie, &threadInfo)
54 				== B_OK) {
55 			// search for the roster thread
56 			if (!strcmp(threadInfo.name, "roster")) {
57 				port_id port = find_port("haiku-test:roster");
58 				port_info portInfo;
59 				if (get_port_info(port, &portInfo) == B_OK
60 					&& portInfo.team == teamInfo.team) {
61 					puts("The Haiku Registrar is already running.");
62 					return 0;
63 				}
64 			}
65 		}
66 	}
67 
68 	// the Haiku registrar doesn't seem to run yet, change this
69 
70 	BPath currentPath(".");
71 
72 	BQuery query;
73 	query.SetPredicate("name==test_registrar");
74 
75 	// search on current volume only
76 	dev_t device = dev_for_path(".");
77 	BVolume volume(device);
78 
79 	query.SetVolume(&volume);
80 	query.Fetch();
81 
82 	entry_ref ref;
83 	while (query.GetNextRef(&ref) == B_OK) {
84 		BPath path(&ref);
85 		if (path.InitCheck() != B_OK)
86 			continue;
87 
88 		const char* registrarPath = path.Path();
89 		const char* generatedPath = strstr(registrarPath, "generated");
90 		if (generatedPath == NULL)
91 			continue;
92 
93 		if (!strncmp(currentPath.Path(), registrarPath, generatedPath - registrarPath)) {
94 			// gotcha!
95 			if (launch_registrar(registrarPath) == B_OK)
96 				return 0;
97 		}
98 	}
99 
100 	// As a fallback (maybe the volume does not support queries for example)
101 	// try to find the test_registrar in the current folder...
102 	BString registrarPath(argv[0]);
103 	registrarPath.RemoveLast(__progname);
104 	registrarPath.Append("test_registrar");
105 	if (launch_registrar(registrarPath.String()) == B_OK)
106 		return 0;
107 
108 	fprintf(stderr, "%s: Could not find the Haiku Registrar.\n"
109 		"    (This tool only works when used in the Haiku tree, but maybe\n"
110 		"    the registrar just needs to be built.)\n",
111 		__progname);
112 	return -1;
113 }
114