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
21extern const char* __progname;
22
23
24static status_t
25launch_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
39int
40main(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