1#include "betalk.h"
2#include "sessions.h"
3#include "rpc_handlers.h"
4#include "rpc_workers.h"
5#include "file_shares.h"
6
7extern bt_fileShare_t fileShares[];
8
9
10void netbtPreMount(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
11{
12	bt_outPacket packet;
13	int client, security;
14
15	client = session->socket;
16	security = btPreMount(session, argv[0].data);
17	btRPCCreateAck(&packet, xid, security);
18	btRPCSendAck(client, &packet);
19}
20
21void netbtMount(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
22{
23	bt_outPacket packet;
24	vnode_id vnid;
25	int client, error;
26	char *shareName = argv[0].data;
27	char *user = argv[1].data;
28	char *password = argv[2].data;
29
30	client = session->socket;
31	error = btMount(session, shareName, user, password, &vnid);
32	if (error == B_OK)
33	{
34		// Record this session having logged in to a specific share.
35		session->share = btGetShareId(shareName);
36		session->logon = time(NULL);
37
38		// Now send the client a response with the root vnid.
39		btRPCCreateAck(&packet, xid, error);
40		btRPCPutInt64(&packet, vnid);
41	}
42	else
43		btRPCCreateAck(&packet, xid, error);
44
45	btRPCSendAck(client, &packet);
46}
47
48void netbtFSInfo(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
49{
50	bt_outPacket packet;
51	fs_info info;
52	int client, error;
53
54	client = session->socket;
55
56	error = btGetFSInfo(fileShares[session->share].path, &info);
57	if (error == B_OK)
58	{
59		btRPCCreateAck(&packet, xid, error);
60		btRPCPutInt32(&packet, info.block_size);
61		btRPCPutInt32(&packet, info.total_blocks);
62		btRPCPutInt32(&packet, info.free_blocks);
63	}
64	else
65		btRPCCreateAck(&packet, xid, error);
66
67	btRPCSendAck(client, &packet);
68}
69
70void netbtLookup(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
71{
72	bt_outPacket packet;
73	struct stat st;
74	int client, error;
75	vnode_id dir_vnid = *((vnode_id *) argv[0].data);
76	vnode_id file_vnid;
77
78	client = session->socket;
79	error = btLookup(session->pathBuffer, dir_vnid, argv[1].data, &file_vnid);
80	if (error == B_OK)
81		error = btStat(session->pathBuffer, file_vnid, &st);
82
83	if (error == B_OK)
84	{
85		btRPCCreateAck(&packet, xid, B_OK);
86		btRPCPutInt64(&packet, file_vnid);
87		btRPCPutStat(&packet, &st);
88	}
89	else
90		btRPCCreateAck(&packet, xid, error);
91
92	btRPCSendAck(client, &packet);
93}
94
95void netbtReadDir(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
96{
97	bt_outPacket packet;
98	struct stat st;
99	int client, error;
100	vnode_id dir_vnid = *((vnode_id *) argv[0].data);
101	vnode_id file_vnid;
102	DIR *dir;
103	char filename[B_PATH_NAME_LENGTH];
104	int entries = 0;
105
106	client = session->socket;
107
108	dir = (DIR *)(*((int32 *) argv[1].data));
109	error = btReadDir(session->pathBuffer, dir_vnid, &dir, &file_vnid, filename, &st);
110
111	if (error != B_OK)
112	{
113		btRPCCreateAck(&packet, xid, error);
114		btRPCSendAck(client, &packet);
115		return;
116	}
117
118	btRPCCreateAck(&packet, xid, B_OK);
119	while (error == B_OK)
120	{
121		btRPCPutInt64(&packet, file_vnid);
122		btRPCPutString(&packet, filename, strlen(filename));
123		btRPCPutInt32(&packet, (int32) dir);
124		btRPCPutStat(&packet, &st);
125
126		if (++entries >= 32)
127			break;
128
129		error = btReadDir(session->pathBuffer, dir_vnid, &dir, &file_vnid, filename, &st);
130		btRPCPutInt32(&packet, error);
131	}
132
133	// If we exhausted the list of directory entries without filling
134	// the buffer, add an error message that will prevent the client
135	// from requesting further entries.
136	if (entries < 32)
137		btRPCPutInt32(&packet, ENOENT);
138
139	btRPCSendAck(client, &packet);
140}
141
142void netbtStat(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
143{
144	bt_outPacket packet;
145	int client, error;
146	struct stat info;
147	vnode_id vnid = *((vnode_id *) argv[0].data);
148
149	client = session->socket;
150	error = btStat(session->pathBuffer, vnid, &info);
151
152	if (error == B_OK)
153	{
154		btRPCCreateAck(&packet, xid, error);
155		btRPCPutStat(&packet, &info);
156	}
157	else
158		btRPCCreateAck(&packet, xid, error);
159
160	btRPCSendAck(client, &packet);
161}
162
163void netbtRead(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
164{
165	bt_outPacket packet;
166	int client;
167	vnode_id vnid = *((vnode_id *) argv[0].data);
168	off_t pos = *((off_t *) argv[1].data);
169	int32 len = *((int32 *) argv[2].data);
170	int32 bytes = 0;
171
172	client = session->socket;
173	session->ioBuffer[len] = 0;
174	bytes = btRead(session->pathBuffer, vnid, pos, len, session->ioBuffer);
175
176	btRPCCreateAck(&packet, xid, B_OK);
177	btRPCPutString(&packet, session->ioBuffer, bytes);
178	btRPCSendAck(client, &packet);
179}
180
181void netbtWrite(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
182{
183	vnode_id vnid = *((vnode_id *) argv[0].data);
184	off_t pos = *((off_t *) argv[1].data);
185	int32 len = *((int32 *) argv[2].data);
186	int32 totalLen = *((int32 *) argv[3].data);
187
188	// If the file share this user is connected to is read-only, the command
189	// cannot be honored.
190	if (session->rights & BT_RIGHTS_WRITE)
191		btWrite(session, vnid, pos, len, totalLen, argv[4].data);
192}
193
194void netbtCreate(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
195{
196	bt_outPacket packet;
197	struct stat st;
198	int client, error;
199	vnode_id dir_vnid = *((vnode_id *) argv[0].data);
200	vnode_id file_vnid;
201	int omode = *((int *) argv[2].data);
202	int perms = *((int *) argv[3].data);
203
204	client = session->socket;
205
206	// If the file share this user is connected to is read-only, the command
207	// cannot be honored.
208	if (!(session->rights & BT_RIGHTS_WRITE))
209	{
210		btRPCCreateAck(&packet, xid, EACCES);
211		btRPCSendAck(client, &packet);
212		return;
213	}
214
215	error = btCreate(session->pathBuffer, dir_vnid, argv[1].data, omode, perms, &file_vnid);
216	if (error == B_OK)
217		error = btStat(session->pathBuffer, file_vnid, &st);
218
219	if (error == B_OK)
220	{
221		btRPCCreateAck(&packet, xid, B_OK);
222		btRPCPutInt64(&packet, file_vnid);
223		btRPCPutStat(&packet, &st);
224	}
225	else
226		btRPCCreateAck(&packet, xid, error);
227
228	btRPCSendAck(client, &packet);
229}
230
231void netbtTruncate(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
232{
233	bt_outPacket packet;
234	int client, error;
235	vnode_id vnid = *((vnode_id *) argv[0].data);
236
237	client = session->socket;
238
239	// If the file share this user is connected to is read-only, the command
240	// cannot be honored.
241	if (!(session->rights & BT_RIGHTS_WRITE))
242	{
243		btRPCCreateAck(&packet, xid, EACCES);
244		btRPCSendAck(client, &packet);
245		return;
246	}
247
248	error = btTruncate(session->pathBuffer, vnid, *((int64 *) argv[1].data));
249	btRPCCreateAck(&packet, xid, error);
250	btRPCSendAck(client, &packet);
251}
252
253void netbtUnlink(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
254{
255	bt_outPacket packet;
256	int client, error;
257	vnode_id vnid = *((vnode_id *) argv[0].data);
258
259	client = session->socket;
260
261	// If the file share this user is connected to is read-only, the command
262	// cannot be honored.
263	if (!(session->rights & BT_RIGHTS_WRITE))
264	{
265		btRPCCreateAck(&packet, xid, EACCES);
266		btRPCSendAck(client, &packet);
267		return;
268	}
269
270	error = btUnlink(session->pathBuffer, vnid, argv[1].data);
271	btRPCCreateAck(&packet, xid, error);
272	btRPCSendAck(client, &packet);
273}
274
275void netbtRename(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
276{
277	bt_outPacket packet;
278	int client, error;
279	vnode_id old_vnid = *((vnode_id *) argv[0].data);
280	vnode_id new_vnid = *((vnode_id *) argv[2].data);
281
282	client = session->socket;
283
284	// If the file share this user is connected to is read-only, the command
285	// cannot be honored.
286	if (!(session->rights & BT_RIGHTS_WRITE))
287	{
288		btRPCCreateAck(&packet, xid, EACCES);
289		btRPCSendAck(client, &packet);
290		return;
291	}
292
293	error = btRename(session->pathBuffer, old_vnid, argv[1].data, new_vnid, argv[3].data);
294	btRPCCreateAck(&packet, xid, error);
295	btRPCSendAck(client, &packet);
296}
297
298void netbtCreateDir(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
299{
300	bt_outPacket packet;
301	int client, error;
302	vnode_id dir_vnid = *((vnode_id *) argv[0].data);
303	vnode_id file_vnid;
304	struct stat st;
305
306	client = session->socket;
307
308	// If the file share this user is connected to is read-only, the command
309	// cannot be honored.
310	if (!(session->rights & BT_RIGHTS_WRITE))
311	{
312		btRPCCreateAck(&packet, xid, EACCES);
313		btRPCSendAck(client, &packet);
314		return;
315	}
316
317	error = btCreateDir(session->pathBuffer, dir_vnid, argv[1].data, *((int *) argv[2].data), &file_vnid, &st);
318	if (error == B_OK)
319	{
320		btRPCCreateAck(&packet, xid, B_OK);
321		btRPCPutInt64(&packet, file_vnid);
322		btRPCPutStat(&packet, &st);
323	}
324	else
325		btRPCCreateAck(&packet, xid, error);
326
327	btRPCSendAck(client, &packet);
328}
329
330void netbtDeleteDir(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
331{
332	bt_outPacket packet;
333	int client, error;
334	vnode_id vnid = *((vnode_id *) argv[0].data);
335
336	client = session->socket;
337
338	// If the file share this user is connected to is read-only, the command
339	// cannot be honored.
340	if (!(session->rights & BT_RIGHTS_WRITE))
341	{
342		btRPCCreateAck(&packet, xid, EACCES);
343		btRPCSendAck(client, &packet);
344		return;
345	}
346
347	error = btDeleteDir(session->pathBuffer, vnid, argv[1].data);
348	btRPCCreateAck(&packet, xid, error);
349	btRPCSendAck(client, &packet);
350}
351
352void netbtReadLink(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
353{
354	bt_outPacket packet;
355	int client, error;
356	char path[B_PATH_NAME_LENGTH];
357	vnode_id vnid = *((vnode_id *) argv[0].data);
358
359	client = session->socket;
360
361	error = btReadLink(session->pathBuffer, vnid, path, B_PATH_NAME_LENGTH);
362	if (error == B_OK)
363	{
364		int length = strlen(path);
365		btRPCCreateAck(&packet, xid, B_OK);
366		btRPCPutString(&packet, path, length);
367	}
368	else
369		btRPCCreateAck(&packet, xid, error);
370
371	btRPCSendAck(client, &packet);
372}
373
374void netbtSymLink(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
375{
376	bt_outPacket packet;
377	int client, error;
378	vnode_id vnid = *((vnode_id *) argv[0].data);
379
380	client = session->socket;
381
382	// If the file share this user is connected to is read-only, the command
383	// cannot be honored.
384	if (!(session->rights & BT_RIGHTS_WRITE))
385	{
386		btRPCCreateAck(&packet, xid, EACCES);
387		btRPCSendAck(client, &packet);
388		return;
389	}
390
391	error = btSymLink(session->pathBuffer, vnid, argv[1].data, argv[2].data);
392	btRPCCreateAck(&packet, xid, error);
393	btRPCSendAck(client, &packet);
394}
395
396void netbtWStat(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
397{
398	bt_outPacket packet;
399	int client, error;
400	vnode_id vnid = *((vnode_id *) argv[0].data);
401	int32 mask = *((int32 *) argv[1].data);
402	int32 mode = *((int32 *) argv[2].data);
403	int32 uid = *((int32 *) argv[3].data);
404	int32 gid = *((int32 *) argv[4].data);
405	int64 size = (int64) *((int32 *) argv[5].data);
406	int32 atime = *((int32 *) argv[6].data);
407	int32 mtime = *((int32 *) argv[7].data);
408
409	client = session->socket;
410
411	// If the file share this user is connected to is read-only, the command
412	// cannot be honored.
413	if (!(session->rights & BT_RIGHTS_WRITE))
414	{
415		btRPCCreateAck(&packet, xid, EACCES);
416		btRPCSendAck(client, &packet);
417		return;
418	}
419
420	error = btWStat(session->pathBuffer, vnid, mask, mode, uid, gid, size, atime, mtime);
421	btRPCCreateAck(&packet, xid, error);
422	btRPCSendAck(client, &packet);
423}
424
425void netbtReadAttrib(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
426{
427	bt_outPacket packet;
428	int client, bytesRead;
429	char *buffer;
430	vnode_id vnid = *((vnode_id *) argv[0].data);
431	int32 type = *((int32 *) argv[2].data);
432	int32 pos = *((int32 *) argv[3].data);
433	int32 len = *((int32 *) argv[4].data);
434
435	client = session->socket;
436
437	if (len <= BT_MAX_ATTR_BUFFER)
438		buffer = session->attrBuffer;
439	else
440		buffer = (char *) malloc(len + 1);
441
442	if (buffer)
443	{
444		bytesRead = btReadAttrib(session->pathBuffer, vnid, argv[1].data, type, buffer, pos, len);
445		if (bytesRead >= 0)
446		{
447			btRPCCreateAck(&packet, xid, B_OK);
448			btRPCPutInt32(&packet, (int32) bytesRead);
449			if (bytesRead > 0)
450				btRPCPutString(&packet, buffer, bytesRead);
451		}
452		else
453			btRPCCreateAck(&packet, xid, B_ENTRY_NOT_FOUND);
454
455		if (len > BT_MAX_ATTR_BUFFER)
456			free(buffer);
457	}
458	else
459		btRPCCreateAck(&packet, xid, ENOMEM);
460
461	btRPCSendAck(client, &packet);
462}
463
464void netbtWriteAttrib(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
465{
466	bt_outPacket packet;
467	int client, bytesWritten;
468	vnode_id vnid = *((vnode_id *) argv[0].data);
469	int32 type = *((int32 *) argv[2].data);
470	int32 pos = *((int32 *) argv[4].data);
471	int32 len = *((int32 *) argv[5].data);
472
473	client = session->socket;
474
475	// If the file share this user is connected to is read-only, the command
476	// cannot be honored.
477	if (!(session->rights & BT_RIGHTS_WRITE))
478	{
479		btRPCCreateAck(&packet, xid, EACCES);
480		btRPCSendAck(client, &packet);
481		return;
482	}
483
484	bytesWritten = btWriteAttrib(session->pathBuffer, vnid, argv[1].data, type, argv[3].data, pos, len);
485	if (bytesWritten >= 0)
486	{
487		btRPCCreateAck(&packet, xid, B_OK);
488		btRPCPutInt32(&packet, (int32) bytesWritten);
489	}
490	else
491		btRPCCreateAck(&packet, xid, B_ENTRY_NOT_FOUND);
492
493	btRPCSendAck(client, &packet);
494}
495
496void netbtReadAttribDir(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
497{
498	bt_outPacket packet;
499	int client, error;
500	vnode_id vnid = *((vnode_id *) argv[0].data);
501	DIR *dir = (DIR *)(*((int32 *) argv[1].data));
502	char attrName[100];
503	int entries = 0;
504
505	client = session->socket;
506
507	error = btReadAttribDir(session->pathBuffer, vnid, &dir, attrName);
508
509	if (error != B_OK)
510	{
511		btRPCCreateAck(&packet, xid, error);
512		btRPCSendAck(client, &packet);
513		return;
514	}
515
516	btRPCCreateAck(&packet, xid, B_OK);
517	while (error == B_OK)
518	{
519		btRPCPutString(&packet, attrName, strlen(attrName));
520		btRPCPutInt32(&packet, (int32) dir);
521
522		if (++entries >= 32)
523			break;
524
525		error = btReadAttribDir(session->pathBuffer, vnid, &dir, attrName);
526		btRPCPutInt32(&packet, error);
527	}
528
529	if (entries < 32)
530		btRPCPutInt32(&packet, ENOENT);
531
532	btRPCSendAck(client, &packet);
533}
534
535void netbtRemoveAttrib(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
536{
537	bt_outPacket packet;
538	int client, error;
539	vnode_id vnid = *((vnode_id *) argv[0].data);
540
541	client = session->socket;
542
543	// If the file share this user is connected to is read-only, the command
544	// cannot be honored.
545	if (!(session->rights & BT_RIGHTS_WRITE))
546	{
547		btRPCCreateAck(&packet, xid, EACCES);
548		btRPCSendAck(client, &packet);
549		return;
550	}
551
552	error = btRemoveAttrib(session->pathBuffer, vnid, argv[1].data);
553	btRPCCreateAck(&packet, xid, error);
554	btRPCSendAck(client, &packet);
555}
556
557void netbtStatAttrib(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
558{
559	bt_outPacket packet;
560	int client, error;
561	vnode_id vnid = *((vnode_id *) argv[0].data);
562	struct attr_info info;
563
564	client = session->socket;
565
566	error = btStatAttrib(session->pathBuffer, vnid, argv[1].data, &info);
567	if (error == B_OK)
568	{
569		btRPCCreateAck(&packet, xid, B_OK);
570		btRPCPutInt32(&packet, info.type);
571		btRPCPutInt64(&packet, info.size);
572	}
573	else
574		btRPCCreateAck(&packet, xid, error);
575
576	btRPCSendAck(client, &packet);
577}
578
579void netbtReadIndexDir(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
580{
581	bt_outPacket packet;
582	int client, error;
583	DIR *dir;
584	char indexName[100];
585
586	client = session->socket;
587
588	dir = (DIR *)(*((int32 *) argv[0].data));
589
590	error = btReadIndexDir(fileShares[session->share].path, &dir, indexName);
591	if (error == B_OK)
592	{
593		btRPCCreateAck(&packet, xid, B_OK);
594		btRPCPutString(&packet, indexName, strlen(indexName));
595		btRPCPutInt32(&packet, (int32) dir);
596	}
597	else
598		btRPCCreateAck(&packet, xid, error);
599
600	btRPCSendAck(client, &packet);
601}
602
603void netbtCreateIndex(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
604{
605	bt_outPacket packet;
606	int client, error;
607	int type = *((int32 *) argv[1].data);
608	int flags = *((int32 *) argv[2].data);
609
610	client = session->socket;
611
612	// If the file share this user is connected to is read-only, the command
613	// cannot be honored.
614	if (!(session->rights & BT_RIGHTS_WRITE))
615	{
616		btRPCCreateAck(&packet, xid, EACCES);
617		btRPCSendAck(client, &packet);
618		return;
619	}
620
621	error = btCreateIndex(fileShares[session->share].path, argv[0].data, type, flags);
622	btRPCCreateAck(&packet, xid, error);
623	btRPCSendAck(client, &packet);
624}
625
626void netbtRemoveIndex(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
627{
628	bt_outPacket packet;
629	int client, error;
630
631	client = session->socket;
632
633	// If the file share this user is connected to is read-only, the command
634	// cannot be honored.
635	if (!(session->rights & BT_RIGHTS_WRITE))
636	{
637		btRPCCreateAck(&packet, xid, EACCES);
638		btRPCSendAck(client, &packet);
639		return;
640	}
641
642	error = btRemoveIndex(fileShares[session->share].path, argv[0].data);
643	btRPCCreateAck(&packet, xid, error);
644	btRPCSendAck(client, &packet);
645}
646
647void netbtStatIndex(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
648{
649	bt_outPacket packet;
650	int client, error;
651	struct index_info info;
652
653	client = session->socket;
654
655	error = btStatIndex(fileShares[session->share].path, argv[0].data, &info);
656	if (error == B_OK)
657	{
658		btRPCCreateAck(&packet, xid, B_OK);
659		btRPCPutInt32(&packet, info.type);
660		btRPCPutInt64(&packet, info.size);
661		btRPCPutInt32(&packet, info.modification_time);
662		btRPCPutInt32(&packet, info.creation_time);
663		btRPCPutInt32(&packet, info.uid);
664		btRPCPutInt32(&packet, info.gid);
665	}
666	else
667		btRPCCreateAck(&packet, xid, error);
668
669	btRPCSendAck(client, &packet);
670}
671
672void netbtReadQuery(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
673{
674	bt_outPacket packet;
675	int client, error;
676	DIR *dir;
677	char fileName[B_PATH_NAME_LENGTH];
678	vnode_id vnid, parent;
679
680	client = session->socket;
681
682	dir = (DIR *)(*((int32 *) argv[0].data));
683
684	error = btReadQuery(fileShares[session->share].path, &dir, argv[1].data, fileName, &vnid, &parent);
685	if (error == B_OK)
686	{
687		btRPCCreateAck(&packet, xid, B_OK);
688		btRPCPutInt64(&packet, vnid);
689		btRPCPutInt64(&packet, parent);
690		btRPCPutString(&packet, fileName, strlen(fileName));
691		btRPCPutInt32(&packet, (int32) dir);
692	}
693	else
694		btRPCCreateAck(&packet, xid, error);
695
696	btRPCSendAck(client, &packet);
697}
698
699// netbtCommit()
700//
701void netbtCommit(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
702{
703	bt_outPacket packet;
704	int client, error;
705	vnode_id vnid = *((vnode_id *) argv[0].data);
706
707	client = session->socket;
708
709	// If the file share this user is connected to is read-only, the command
710	// cannot be honored.
711	if (!(session->rights & BT_RIGHTS_WRITE))
712	{
713		btRPCCreateAck(&packet, xid, EACCES);
714		btRPCSendAck(client, &packet);
715		return;
716	}
717
718	error = btCommit(session, vnid);
719	btRPCCreateAck(&packet, xid, error);
720	btRPCSendAck(client, &packet);
721}
722
723void netbtPrintJobNew(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
724{
725}
726
727void netbtPrintJobData(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
728{
729}
730
731void netbtPrintJobCommit(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
732{
733}
734
735void netbtAuthenticate(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
736{
737}
738
739// netbtQuit()
740//
741void netbtQuit(bt_session_t *session, unsigned int xid, int argc, bt_arg_t argv[])
742{
743	bt_outPacket packet;
744	int client;
745
746	client = session->socket;
747	btRPCCreateAck(&packet, xid, B_OK);
748	btRPCSendAck(client, &packet);
749}
750