1#include <Message.h>
2#include <Entry.h>
3#include <File.h>
4#include <NodeMonitor.h>
5#include <kernel/fs_info.h>
6#include <kernel/fs_query.h>
7
8#include <stdio.h>
9#include <string.h>
10
11#ifndef B_BAD_DATA
12#	define B_BAD_DATA B_ERROR
13#endif
14
15#define DUMPED_BLOCK_SIZE 16
16#define Print printf
17
18void
19dumpBlock(const char *buffer,int size)
20{
21	for(int i = 0;i < size;) {
22		int start = i;
23
24		for(;i < start+DUMPED_BLOCK_SIZE;i++) {
25			if (!(i % 4))
26				Print(" ");
27
28			if (i >= size)
29				Print("  ");
30			else
31				Print("%02x",*(unsigned char *)(buffer+i));
32		}
33		Print("  ");
34
35		for(i = start;i < start + DUMPED_BLOCK_SIZE;i++) {
36			if (i < size) {
37				char c = *(buffer+i);
38
39				if (c < 30)
40					Print(".");
41				else
42					Print("%c",c);
43			}
44			else
45				break;
46		}
47		Print("\n");
48	}
49}
50
51
52void
53createFile(int32 num)
54{
55	char name[B_FILE_NAME_LENGTH];
56	sprintf(name,"./_query_test_%ld",num);
57
58	BFile file(name,B_CREATE_FILE | B_WRITE_ONLY);
59}
60
61
62BEntry *
63getEntry(int32 num)
64{
65	char name[B_FILE_NAME_LENGTH];
66	sprintf(name,"./_query_test_%ld",num);
67
68	return new BEntry(name);
69}
70
71
72status_t
73waitForMessage(port_id port,const char *string,int32 op,char *name)
74{
75	puts(string);
76
77	int32 msg;
78	char buffer[1024];
79	ssize_t bytes = read_port_etc(port,&msg,buffer,sizeof(buffer),B_TIMEOUT,1000000);
80	if (op == B_TIMED_OUT && bytes == B_TIMED_OUT) {
81		puts("  passed, timed out!\n");
82		return bytes;
83	}
84	if (bytes < B_OK) {
85		printf("-> %s\n\n", strerror(bytes));
86		return bytes;
87	}
88
89	BMessage message;
90	if (message.Unflatten(buffer) < B_OK) {
91		printf("could not unflatten message:\n");
92		dumpBlock(buffer, bytes);
93		return B_BAD_DATA;
94	}
95
96	if (message.what != B_QUERY_UPDATE
97		|| message.FindInt32("opcode") != op) {
98		printf("Expected what = %x, opcode = %ld, got:", B_QUERY_UPDATE, op);
99		message.PrintToStream();
100		putchar('\n');
101		return message.FindInt32("opcode");
102	}
103	puts("  passed!\n");
104	return op;
105}
106
107
108int
109main(int argc,char **argv)
110{
111	port_id port = create_port(100, "query port");
112	printf("port id = %ld\n", port);
113	printf("  B_ENTRY_REMOVED = %d, B_ENTRY_CREATED = %d\n\n", B_ENTRY_REMOVED, B_ENTRY_CREATED);
114
115	dev_t device = dev_for_path(".");
116	DIR *query = fs_open_live_query(device, "name=_query_test_*", B_LIVE_QUERY, port, 12345);
117
118	createFile(1);
119	waitForMessage(port, "File 1 created:", B_ENTRY_CREATED, "_query_test_1");
120
121	createFile(2);
122	waitForMessage(port, "File 2 created:", B_ENTRY_CREATED, "_query_test_2");
123
124	BEntry *entry = getEntry(2);
125	if (entry->InitCheck() < B_OK) {
126		fprintf(stderr, "Could not get entry for file 2\n");
127		fs_close_query(query);
128		return -1;
129	}
130	entry->Rename("_some_other_name_");
131	waitForMessage(port,"File 2 renamed (should fall out of query):", B_ENTRY_REMOVED, NULL);
132
133	entry->Rename("_some_other_");
134	waitForMessage(port,"File 2 renamed again (should time out):", B_TIMED_OUT, NULL);
135
136	entry->Rename("_query_test_2");
137	waitForMessage(port,"File 2 renamed back (should be added to query):",
138		B_ENTRY_CREATED, "_query_test_2");
139
140	entry->Rename("_query_test_2_and_more");
141	status_t status = waitForMessage(port,"File 2 renamed (should stay in query, time out):",
142							B_TIMED_OUT, "_query_test_2_and_more");
143	if (status == B_ENTRY_REMOVED) {
144		waitForMessage(port,"Received B_ENTRY_REMOVED, now expecting file 2 to be added again:",
145			B_ENTRY_CREATED, NULL);
146	}
147
148	entry->Remove();
149	delete entry;
150	waitForMessage(port,"File 2 removed:", B_ENTRY_REMOVED, NULL);
151
152	entry = getEntry(1);
153	if (entry->InitCheck() < B_OK) {
154		fprintf(stderr, "Could not get entry for file 1\n");
155		fs_close_query(query);
156		return -1;
157	}
158
159	entry->Rename("_some_other_name_");
160	waitForMessage(port, "File 1 renamed (should fall out of query):", B_ENTRY_REMOVED, NULL);
161
162	entry->Remove();
163	delete entry;
164	waitForMessage(port, "File 1 removed (should time out):", B_TIMED_OUT, NULL);
165
166	fs_close_query(query);
167
168	return 0;
169}
170
171