1// NetFSServerRoster.cpp
2
3#include <string.h>
4
5#include <Message.h>
6#include <OS.h>
7#include <Roster.h>
8
9#include "NetFSServerRoster.h"
10#include "NetFSServerRosterDefs.h"
11
12// constructor
13NetFSServerRoster::NetFSServerRoster()
14	: fServerMessenger()
15{
16}
17
18// destructor
19NetFSServerRoster::~NetFSServerRoster()
20{
21}
22
23// IsServerRunning
24bool
25NetFSServerRoster::IsServerRunning()
26{
27	return (_InitMessenger() == B_OK);
28}
29
30// LaunchServer
31status_t
32NetFSServerRoster::LaunchServer()
33{
34	status_t error = BRoster().Launch(kNetFSServerSignature);
35	if (error != B_OK)
36		return error;
37
38	return _InitMessenger();
39}
40
41// TerminateServer
42status_t
43NetFSServerRoster::TerminateServer(bool force, bigtime_t timeout)
44{
45	// get the server team
46	team_id team = BRoster().TeamFor(kNetFSServerSignature);
47	if (team < 0)
48		return team;
49
50	// create a semaphore an transfer its ownership to the server team
51	sem_id deathSem = create_sem(0, "netfs server death");
52	set_sem_owner(deathSem, team);
53
54	status_t error = B_OK;
55	if (force) {
56		// terminate it the hard way
57		kill_team(team);
58
59		// wait the specified time
60		error = acquire_sem_etc(deathSem, 1, B_RELATIVE_TIMEOUT, timeout);
61	} else {
62		// get a messenger
63		BMessenger messenger(NULL, team);
64		if (messenger.IsValid()) {
65			// tell the server to quit
66			messenger.SendMessage(B_QUIT_REQUESTED);
67
68			// wait the specified time
69			error = acquire_sem_etc(deathSem, 1, B_RELATIVE_TIMEOUT, timeout);
70		} else
71			error = B_ERROR;
72	}
73
74	delete_sem(deathSem);
75
76	// if the semaphore is gone, the server is gone, as well
77	return (error == B_BAD_SEM_ID ? B_OK : B_ERROR);
78}
79
80// SaveServerSettings
81status_t
82NetFSServerRoster::SaveServerSettings()
83{
84	// prepare the request
85	BMessage request(NETFS_REQUEST_SAVE_SETTINGS);
86
87	// send the request
88	return _SendRequest(&request);
89}
90
91
92// #pragma mark -
93
94// AddUser
95status_t
96NetFSServerRoster::AddUser(const char* user, const char* password)
97{
98	// check parameters
99	if (!user || strlen(user) < 1)
100		return B_BAD_VALUE;
101
102	// prepare the request
103	BMessage request(NETFS_REQUEST_ADD_USER);
104	if (request.AddString("user", user) != B_OK
105		|| (password && request.AddString("password", password) != B_OK)) {
106		return B_ERROR;
107	}
108
109	// send the request
110	return _SendRequest(&request);
111}
112
113// RemoveUser
114status_t
115NetFSServerRoster::RemoveUser(const char* user)
116{
117	// check parameters
118	if (!user || strlen(user) < 1)
119		return B_BAD_VALUE;
120
121	// prepare the request
122	BMessage request(NETFS_REQUEST_REMOVE_USER);
123	if (request.AddString("user", user) != B_OK)
124		return B_ERROR;
125
126	// send the request
127	return _SendRequest(&request);
128}
129
130// GetUsers
131status_t
132NetFSServerRoster::GetUsers(BMessage* users)
133{
134	// check parameters
135	if (!users)
136		return B_BAD_VALUE;
137
138	// prepare the request
139	BMessage request(NETFS_REQUEST_GET_USERS);
140
141	// send the request
142	BMessage reply;
143	status_t error = _SendRequest(&request, &reply);
144	if (error != B_OK)
145		return error;
146
147	// get the result
148	if (reply.FindMessage("users", users) != B_OK)
149		return B_ERROR;
150
151	return B_OK;
152}
153
154// GetUserStatistics
155status_t
156NetFSServerRoster::GetUserStatistics(const char* user, BMessage* statistics)
157{
158	// check parameters
159	if (!user || strlen(user) < 1 || !statistics)
160		return B_BAD_VALUE;
161
162	// prepare the request
163	BMessage request(NETFS_REQUEST_GET_USER_STATISTICS);
164	if (request.AddString("user", user) != B_OK)
165		return B_ERROR;
166
167	// send the request
168	BMessage reply;
169	status_t error = _SendRequest(&request, &reply);
170	if (error != B_OK)
171		return error;
172
173	// get the result
174	if (reply.FindMessage("statistics", statistics) != B_OK)
175		return B_ERROR;
176
177	return B_OK;
178}
179
180
181// #pragma mark -
182
183// AddShare
184status_t
185NetFSServerRoster::AddShare(const char* share, const char* path)
186{
187	// check parameters
188	if (!share || strlen(share) < 1 || !path || strlen(path) < 1)
189		return B_BAD_VALUE;
190
191	// prepare the request
192	BMessage request(NETFS_REQUEST_ADD_SHARE);
193	if (request.AddString("share", share) != B_OK
194		|| request.AddString("path", path) != B_OK) {
195		return B_ERROR;
196	}
197
198	// send the request
199	return _SendRequest(&request);
200}
201
202// RemoveShare
203status_t
204NetFSServerRoster::RemoveShare(const char* share)
205{
206	// check parameters
207	if (!share || strlen(share) < 1)
208		return B_BAD_VALUE;
209
210	// prepare the request
211	BMessage request(NETFS_REQUEST_REMOVE_SHARE);
212	if (request.AddString("share", share) != B_OK)
213		return B_ERROR;
214
215	// send the request
216	return _SendRequest(&request);
217}
218
219// GetShares
220status_t
221NetFSServerRoster::GetShares(BMessage* shares)
222{
223	// check parameters
224	if (!shares)
225		return B_BAD_VALUE;
226
227	// prepare the request
228	BMessage request(NETFS_REQUEST_GET_SHARES);
229
230	// send the request
231	BMessage reply;
232	status_t error = _SendRequest(&request, &reply);
233	if (error != B_OK)
234		return error;
235
236	// get the result
237	if (reply.FindMessage("shares", shares) != B_OK)
238		return B_ERROR;
239
240	return B_OK;
241}
242
243// GetShareUsers
244status_t
245NetFSServerRoster::GetShareUsers(const char* share, BMessage* users)
246{
247	// check parameters
248	if (!share || strlen(share) < 1 || !users)
249		return B_BAD_VALUE;
250
251	// prepare the request
252	BMessage request(NETFS_REQUEST_GET_SHARE_USERS);
253	if (request.AddString("share", share) != B_OK)
254		return B_ERROR;
255
256	// send the request
257	BMessage reply;
258	status_t error = _SendRequest(&request, &reply);
259	if (error != B_OK)
260		return error;
261
262	// get the result
263	if (reply.FindMessage("users", users) != B_OK)
264		return B_ERROR;
265
266	return B_OK;
267}
268
269// GetShareStatistics
270status_t
271NetFSServerRoster::GetShareStatistics(const char* share, BMessage* statistics)
272{
273	// check parameters
274	if (!share || strlen(share) < 1 || !statistics)
275		return B_BAD_VALUE;
276
277	// prepare the request
278	BMessage request(NETFS_REQUEST_GET_SHARE_STATISTICS);
279	if (request.AddString("share", share) != B_OK)
280		return B_ERROR;
281
282	// send the request
283	BMessage reply;
284	status_t error = _SendRequest(&request, &reply);
285	if (error != B_OK)
286		return error;
287
288	// get the result
289	if (reply.FindMessage("statistics", statistics) != B_OK)
290		return B_ERROR;
291
292	return B_OK;
293}
294
295
296// #pragma mark -
297
298// SetUserPermissions
299status_t
300NetFSServerRoster::SetUserPermissions(const char* share, const char* user,
301	uint32 permissions)
302{
303	// check parameters
304	if (!share || strlen(share) < 1 || !user || strlen(user) < 1)
305		return B_BAD_VALUE;
306
307	// prepare the request
308	BMessage request(NETFS_REQUEST_SET_USER_PERMISSIONS);
309	if (request.AddString("share", share) != B_OK
310		|| request.AddString("user", user) != B_OK
311		|| request.AddInt32("permissions", (int32)permissions)) {
312		return B_ERROR;
313	}
314
315	// send the request
316	return _SendRequest(&request);
317}
318
319// GetUserPermissions
320status_t
321NetFSServerRoster::GetUserPermissions(const char* share, const char* user,
322	uint32* permissions)
323{
324	// check parameters
325	if (!share || strlen(share) < 1 || !user || strlen(user) < 1
326		|| !permissions) {
327		return B_BAD_VALUE;
328	}
329
330	// prepare the request
331	BMessage request(NETFS_REQUEST_GET_USER_PERMISSIONS);
332	if (request.AddString("share", share) != B_OK
333		|| request.AddString("user", user) != B_OK) {
334		return B_ERROR;
335	}
336
337	// send the request
338	BMessage reply;
339	status_t error = _SendRequest(&request, &reply);
340	if (error != B_OK)
341		return error;
342
343	// get the result
344	if (reply.FindInt32("permissions", (int32*)permissions) != B_OK)
345		return B_ERROR;
346
347	return B_OK;
348}
349
350// #pragma mark -
351
352// _InitMessenger
353status_t
354NetFSServerRoster::_InitMessenger()
355{
356	// do we already have a valid messenger?
357	if (fServerMessenger.IsValid())
358		return B_OK;
359
360	// get a messenger to the server application
361	BMessenger appMessenger(kNetFSServerSignature);
362	if (!appMessenger.IsValid())
363		return B_NO_INIT;
364
365	// send a request to get the real messenger
366	BMessage request(NETFS_REQUEST_GET_MESSENGER);
367	BMessage reply;
368	if (appMessenger.SendMessage(&request, &reply) != B_OK)
369		return B_NO_INIT;
370
371	// check the result
372	status_t error;
373	if (reply.FindInt32("error", &error) != B_OK)
374		return B_ERROR;
375	if (error != B_OK)
376		return error;
377
378	// get the messenger
379	if (reply.FindMessenger("messenger", &fServerMessenger) != B_OK)
380		return B_NO_INIT;
381
382	return (fServerMessenger.IsValid() ? B_OK : B_NO_INIT);
383}
384
385// _SendRequest
386status_t
387NetFSServerRoster::_SendRequest(BMessage* request, BMessage* reply)
388{
389	// if no reply data are expected, create a reply message on the stack
390	BMessage stackReply;
391	if (!reply)
392		reply = &stackReply;
393
394	// make sure the messenger is initialized
395	status_t error = _InitMessenger();
396	if (error != B_OK)
397		return error;
398
399	// send the request
400	error = fServerMessenger.SendMessage(request, reply);
401	if (error != B_OK)
402		return error;
403
404	// check the reply result
405	status_t result;
406	if (reply->FindInt32("error", &result) != B_OK)
407		return B_ERROR;
408	return result;
409}
410