source: tags/0.58/stoposserver.cpp @ 9

Last change on this file since 9 was 9, checked in by willem, 11 years ago

willem

File size: 7.9 KB
Line 
1#include <iostream>
2#include <stdlib.h>
3#include <vector>
4#include <string>
5#include "stopos.h"
6#include "wutils.h"
7#include "stopos_pool.h"
8#include "gdbm_pool.h"
9#include "flatfile_pool.h"
10#include "files_pool.h"
11#include "mysql_pool.h"
12
13void output(const std::string &return_message, const std::string &key,
14             longuint committed, 
15             longuint count,
16             longuint present,
17             longuint present0,
18             const std::string &return_value)
19{
20  std::cout << "STOPOS:"                            << outsep <<
21               zstrtohex(return_message)            << outsep <<
22               zstrtohex(key)                       << outsep <<
23               zstrtohex(NumberToString(committed)) << outsep <<
24               zstrtohex(NumberToString(count))     << outsep <<
25               zstrtohex(NumberToString(present))   << outsep <<
26               zstrtohex(NumberToString(present0))  << outsep <<
27               zstrtohex(return_value)              << 
28               std::endl;
29}
30
31void output(const std::string &msg)
32{
33  output(msg,"",0,0,0,0,"");
34}
35struct commandline
36{
37  std::string header;
38  std::string prot;
39  std::string id;
40  std::string pool;
41  std::string command;
42  std::string multi;
43  std::string value;
44  std::string full_dbname;
45  std::string return_value;
46  stopos_pool *handler;
47
48  int create_full_dbname(void)
49  {
50    if (this->prot == "gdbm" ||
51        this->prot == "flat" ||
52        this->prot == "files")
53    {
54      this->full_dbname = "/tmp/"              +
55                          zstrtohex(this->id)   +
56                          "/"                  +
57                          zstrtohex(this->pool) +
58                          "_"                  +
59                          this->prot;
60    }
61    else if (this->prot == "mysql")
62    {
63      this->full_dbname = zstrtohex(this->id) +
64                          "_"                +
65                          zstrtohex(this->pool);
66    }
67    else
68      return 1;
69
70    if (this->command != "pools")
71      this->handler->set_db_name(this->full_dbname);
72    return 0;
73  }
74
75  int create_handler()
76  {
77    if (this->prot == "gdbm")
78    {
79      this->handler = new gdbm_pool();
80    }
81    if (this->prot == "flat")
82    {
83      this->handler = new flatfile_pool();
84    }
85    if (this->prot == "files")
86    {
87      this->handler = new files_pool();
88    }
89    if (this->prot == "mysql")
90    {
91      this->handler = new mysql_pool();
92    }
93    return 0;
94  }
95
96  int init()
97  {
98
99    int rc;
100    if (this->command != "pools")
101    {
102      rc = this->create_handler();
103      if (rc != 0) 
104        return rc;
105      if (this->multi == "yes")
106        this->handler->set_kvp(1);
107      else
108        this->handler->set_kvp(0);
109    }
110    rc = this->create_full_dbname();
111    return rc;
112  }
113
114  int create_db()
115  {
116    int rc = this->handler->create_db();
117    return rc;
118  }
119
120  int purge_db()
121  {
122    int rc = this->handler->purge_db();
123    return rc;
124  }
125
126  int add_line(std::string &key, std::string &r)
127  {
128    r = "";
129    int rc;
130    rc = this->handler->open_db();
131    if (rc != 0)
132    {
133      r = "ERROR: cannot open pool "+this->pool;
134      return rc;
135    }
136
137    rc = this->handler->add_line(this->value,key);
138    if (rc != 0)
139    {
140      r = "ERROR: cannot write to pool "+this->pool;
141      return rc;
142    }
143    return 0;
144  }
145
146  int get_line(std::string &key, longuint &comm, std::string &r)
147  {
148    r = "";
149    int rc;
150    rc = this->handler->open_db();
151    if (rc != 0)
152    {
153      r = "ERROR: cannot open pool "+this->pool;
154      return rc;
155    }
156    rc = this->handler->get_line(this->return_value, comm, key);
157    return rc;
158  }
159
160  int dump_line(std::string &key, longuint &comm, std::string &r)
161  {
162    r = "";
163    int rc;
164    rc = this->handler->open_db();
165    if (rc != 0)
166    {
167      r = "ERROR: cannot open pool "+this->pool;
168      return rc;
169    }
170    rc = this->handler->dump_line(this->return_value, comm, key);
171    return rc;
172  }
173
174  int remove_line(std::string & rkey,std::string &key, std::string &r)
175  {
176    r = "";
177    int rc;
178    rc = this->handler->open_db();
179    if (rc != 0)
180    {
181      r = "ERROR: cannot open pool "+this->pool;
182      return rc;
183    }
184    rkey = key;
185    rc = this->handler->remove_line(key);
186    return rc;
187  }
188
189  int get_status(longuint &count, 
190                 longuint &present, 
191                 longuint &present0, std::string &r)
192  {
193    r = "";
194    int rc;
195    rc = this->handler->open_db();
196    if (rc != 0)
197    {
198      r = "ERROR: cannot open pool "+this->pool;
199      return rc;
200    }
201    rc = this->handler->get_counts(count, present, present0);
202
203    return rc;
204  }
205};
206
207std::string sanitycheck(commandline &l)
208{
209  if (l.header != "stopos")
210    return "invalid header";
211
212  if (l.prot.find_first_of(' ') != l.prot.npos)
213    return "no valid protocol given";
214
215  if(l.id.find_first_of(' ') != l.id.npos)
216    return "no valid id given";
217
218  if(l.command != "pools")
219    if(l.pool.find_first_of(' ') != l.pool.npos)
220    {
221      return "no valid pool given";
222    }
223  if(l.command.find_first_of(' ') != l.command.npos)
224  {
225    return "no valid command given";
226  }
227  return "";
228}
229
230int parsecom(commandline &l,std::string &line)
231{
232  std::vector <std::string> v;
233  split(v,line,httpsep); 
234                       
235  for (unsigned int i =0; i<v.size(); i++)
236  {
237    switch(i)
238    {
239      case 0: l.header   = zhextostr(v[i]); break;
240      case 1: l.prot     = zhextostr(v[i]); break;
241      case 2: l.id       = zhextostr(v[i]); break;
242      case 3: l.pool     = zhextostr(v[i]); break;
243      case 4: l.command  = zhextostr(v[i]); break;
244      case 5: l.multi    = zhextostr(v[i]); break;
245      case 6: l.value    = zhextostr(v[i]); break;
246    }
247  }
248  return 0;
249}
250
251
252int executecom(commandline &l)
253{
254  int rc;
255  longuint committed = 0;
256  longuint count     = 0;
257  longuint present   = 0;
258  longuint present0  = 0;
259
260  std::string return_message;
261  std::string key;
262  rc = l.init();
263
264  if (rc != 0)
265  {
266    output("ERROR: cannot initialize server software");
267    return rc;
268  }
269
270  if (l.command == "create")
271  {
272    rc = l.create_db();
273    if (rc != 0)
274      return_message = "ERROR: cannot create pool "+l.pool;
275  }
276  else if (l.command == "purge")
277  {
278    rc = l.purge_db();
279  }
280  else if (l.command == "add")
281  {
282    rc = l.add_line(key,return_message);
283  }
284  else if (l.command == "next")
285  {
286    rc = l.get_line(key, committed,return_message);
287  }
288  else if (l.command == "dump")
289  {
290    rc = l.dump_line(key, committed,return_message);
291  }
292  else if (l.command == "remove")
293  {
294    rc = l.remove_line(key,l.value, return_message);
295  }
296  else if (l.command == "status")
297  {
298    rc = l.get_status(count,present,present0,return_message);
299  }
300  else if (l.command == "pools")
301  {
302    if      (l.prot == "mysql")
303    {
304      l.return_value = "No pools for mysql";
305      rc = 0;
306    }
307    else if (l.prot == "files" ||
308             l.prot == "gdbm"  ||
309             l.prot == "flat"  )
310    {
311      // extract the directory from full_dbname:
312      size_t p = l.full_dbname.find_last_of('/');
313      if (p == l.full_dbname.npos)
314        rc = 1;
315      else
316      {
317        std::string dir = l.full_dbname.substr(0,p+1);
318        std::list <std::string> v;
319        get_dir_list(v,dir);
320        v.sort();
321
322        l.return_value = "";
323        for (std::list<std::string>::iterator it=v.begin(); it != v.end(); ++it)
324        {
325          std::string f = *it;
326          //
327          // if suffix ( eg: _files ) is found
328          // this could be a valid file name
329          //
330
331          p = f.rfind("_"+l.prot);
332          if (p == f.npos)
333            continue;
334          f = f.substr(0,p);
335          //
336          // strip directory part
337          //
338          p = f.find_last_of('/');
339          f = f.substr(p+1);
340          l.return_value += zhextostr(f);
341          l.return_value.push_back(' ');
342        }
343        if (l.return_value.size() > 0)
344          l.return_value.erase(l.return_value.size()-1);
345      }
346      rc = 0;
347    }
348  }
349  else rc = 1;
350  if (rc == 0)
351    return_message="OK";
352  else
353    if (return_message == "")
354      return_message="ERROR";
355
356  output(return_message, key, committed, count,
357         present, present0, l.return_value);
358  return rc;
359}
360
361int main()
362{
363  int rc;
364  std::cout << "Content-Type: text/plain\n\n";
365  std::string line;
366  line = envtostr("PATH_INFO");
367  if (line.size() >0)
368    if (line[0] == '/')
369      line.erase(0,1);
370
371  commandline l;
372  parsecom(l,line);
373  std::string msg = sanitycheck(l);
374  if (msg != "")
375  {
376    output(msg);
377    return 1;
378  }
379  rc = executecom(l);
380
381  return rc;
382}
Note: See TracBrowser for help on using the repository browser.