1
/* This file is part of Strigi Desktop Search
3
* Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public License
16
* along with this library; see the file COPYING.LIB. If not, write to
17
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
* Boston, MA 02110-1301, USA.
20
#include <strigi/socketclient.h>
21
#include <sys/types.h>
22
#include <sys/socket.h>
36
#if defined(__APPLE__)
37
#define SOCKET_NOSIGNAL SO_NOSIGPIPE
38
#elif defined( MSG_NOSIGNAL )
39
#define SOCKET_NOSIGNAL MSG_NOSIGNAL
41
#define SOCKET_NOSIGNAL 0
45
SocketClient::setSocketName(const string& n) {
49
SocketClient::open() {
50
struct sockaddr_un serv_addr;
53
int sd = socket(AF_UNIX, SOCK_STREAM, 0);
55
error = "Could not create socket: ";
56
error += strerror(errno);
61
memset(&serv_addr, 0, sizeof(serv_addr));
62
serv_addr.sun_family = AF_UNIX;
63
size_t len = socketpath.length();
64
len = (len > sizeof(serv_addr.sun_path)) ?sizeof(serv_addr.sun_path) :len;
65
strncpy(serv_addr.sun_path, socketpath.c_str(), len);
66
serv_addr.sun_path[len] = '\0';
68
// connect to the server
69
int r = connect(sd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
71
error = "Could not connect to server: ";
72
error += strerror(errno);
79
SocketClient::readResponse(int sd) {
84
// read characters one by one
85
ssize_t r = recv(sd, &c, 1, 0);
87
error = "Error reading from socket: ";
88
error += strerror(errno);
89
printf("%s\n", error.c_str());
91
} else if (r == 0 || c == 0) {
92
if (line.size() > 0) {
93
response.push_back(line);
96
} else if (c == '\n') {
97
if (line.size() == 0) {
98
// finished reading the request
101
response.push_back(line);
109
SocketClient::sendRequest(int sd) {
111
for (uint i=0; i<request.size(); ++i) {
112
string line = request[i];
113
assert(line.find('\n') == string::npos);
116
size_t len = line.length();
118
r = send(sd, line.c_str()+p, len-p, SOCKET_NOSIGNAL);
120
printf("error writing request\n");
126
r = send(sd, "\n", 1, SOCKET_NOSIGNAL);
130
SocketClient::countHits(const string &query) {
133
request.push_back("countHits");
134
assert(query.find("\n") == string::npos);
135
request.push_back(query);
138
fprintf(stderr, " %s\n", error.c_str());
144
if (response.size() == 0) return -1;
145
int count = atoi(response[0].c_str());
148
ClientInterface::Hits
149
SocketClient::getHits(const string &query, uint32_t max, uint32_t off) {
152
request.push_back("query");
153
assert(query.find("\n") == string::npos);
154
request.push_back(query);
157
request.push_back(oss.str());
160
request.push_back(oss.str());
164
printf(" %s\n", error.c_str());
172
while (i+6 < response.size()) {
173
Strigi::IndexedDocument h;
174
h.uri = response[i++];
175
h.fragment = response[i++];
176
h.mimetype = response[i++];
177
h.score = (float)atof(response[i++].c_str());
178
h.size = atoi(response[i++].c_str());
179
h.mtime = atoi(response[i++].c_str());
180
while (i < response.size()) {
181
const char* s = response[i].c_str();
182
const char* v = strchr(s, ':');
184
const char* d = strchr(s, '/');
189
h.properties.insert(make_pair<const string,string>(n,v+1));
192
hits.hits.push_back(h);
198
SocketClient::getStatus() {
199
map<string, string> status;
202
request.push_back("getStatus");
205
// no connection: return an empty map
206
//printf(" %s\n", error.c_str());
207
//status["error"] = error;
213
for (uint i=0; i<response.size(); ++i) {
214
string s = response[i];
215
string::size_type p = s.find(":");
216
if (p == string::npos) {
217
printf("''%s''\n", s.c_str());
219
status["error"] = "Communication error.";
222
status[s.substr(0,p)] = s.substr(p+1);
227
SocketClient::getBackEnds() {
232
SocketClient::stopDaemon() {
234
request.push_back("stopDaemon");
245
SocketClient::startIndexing() {
247
request.push_back("startIndexing");
258
SocketClient::stopIndexing() {
260
request.push_back("stopIndexing");
271
SocketClient::getIndexedDirectories() {
275
request.push_back("getIndexedDirectories");
283
vector<string>::const_iterator i;
284
for (i = response.begin(); i != response.end(); ++i) {
290
SocketClient::setIndexedDirectories(set<string> dirs) {
292
request.push_back("setIndexedDirectories");
293
set<string>::const_iterator i;
294
for (i = dirs.begin(); i != dirs.end(); ++i) {
295
request.push_back(*i);
307
SocketClient::setFilters(const vector<pair<bool,string> >&rules){
309
vector<pair<bool,string> >
310
SocketClient::getFilters() {
311
vector<pair<bool,string> > f;
315
SocketClient::getIndexedFiles() {
319
request.push_back("getIndexedFiles");
327
vector<string>::const_iterator i;
328
for (i = response.begin(); i != response.end(); ++i) {
334
SocketClient::indexFile(const string &path, uint64_t mtime,
335
const vector<char>& content) {
336
printf("so you want me to send a file to strigi?\n");
339
request.push_back("indexFile");
340
request.push_back(path);
343
request.push_back(out.str());
344
request.push_back(&content[0]);
347
SocketClient::getFieldNames() {
348
fprintf(stderr, "SocketClient::getFieldNames is not implemented yet\n");
349
return vector<string>();
351
vector<pair<string, uint32_t> >
352
SocketClient::getHistogram(const string& query, const string& field,
353
const string& labeltype) {
354
fprintf(stderr, "SocketClient::getHistogram is not implemented yet\n");
355
return vector<pair<string, uint32_t> >();
358
SocketClient::countKeywords(const string& keywordmatch,
359
const vector<string>& fieldnames) {
360
fprintf(stderr, "SocketClient::countKeywords is not implemented yet\n");
364
SocketClient::getKeywords(const string& keywordprefix,
365
const vector<string>& fieldnames,
366
uint32_t max, uint32_t offset) {
367
fprintf(stderr, "SocketClient::getKeywords is not implemented yet\n");
368
return vector<string>();