Line data Source code
1 : #include "../../burp.h"
2 : #include "../../alloc.h"
3 : #include "../../asfd.h"
4 : #include "../../async.h"
5 : #include "../../bu.h"
6 : #include "../../cstat.h"
7 : #include "../../handy.h"
8 : #include "../../iobuf.h"
9 : #include "../../log.h"
10 : #include "cstat.h"
11 : #include "json_output.h"
12 : #include "status_server.h"
13 :
14 0 : static int parse_parent_data(struct asfd *asfd, struct cstat *clist)
15 : {
16 0 : int ret=-1;
17 0 : char *cp=NULL;
18 0 : char *cname=NULL;
19 0 : struct cstat *c=NULL;
20 0 : char *path=NULL;
21 : //printf("got parent data: '%s'\n", asfd->rbuf->buf);
22 :
23 : // Extract the client name.
24 0 : if(!(cp=strchr(asfd->rbuf->buf, '\t')))
25 : return 0;
26 0 : *cp='\0';
27 0 : if(!(cname=strdup_w(asfd->rbuf->buf, __func__))) goto end;
28 0 : *cp='\t';
29 :
30 : // Find the array entry for this client,
31 : // and add the detail from the parent to it.
32 0 : for(c=clist; c; c=c->next)
33 : {
34 0 : if(!strcmp(c->name, cname))
35 : {
36 : //printf("parse for client %s\n", c->name);
37 0 : if(str_to_cntr(asfd->rbuf->buf, c, &path))
38 : goto end;
39 : }
40 : }
41 :
42 : // FIX THIS: Do something with path.
43 :
44 : ret=0;
45 : end:
46 0 : free_w(&cname);
47 0 : free_w(&path);
48 : return ret;
49 : }
50 :
51 0 : static char *get_str(const char **buf, const char *pre, int last)
52 : {
53 0 : size_t len=0;
54 0 : char *cp=NULL;
55 0 : char *copy=NULL;
56 0 : char *ret=NULL;
57 0 : if(!buf || !*buf) goto end;
58 0 : len=strlen(pre);
59 0 : if(strncmp(*buf, pre, len)
60 0 : || !(copy=strdup_w((*buf)+len, __func__)))
61 : goto end;
62 0 : if(!last && (cp=strchr(copy, ':'))) *cp='\0';
63 0 : *buf+=len+strlen(copy)+1;
64 0 : ret=strdup_w(copy, __func__);
65 : end:
66 0 : free_w(©);
67 0 : return ret;
68 : }
69 :
70 : /*
71 : void dump_cbno(struct cstat *clist, const char *msg)
72 : {
73 : if(!clist) return;
74 : printf("dump %s: %s\n", msg, clist->name);
75 : struct bu *b;
76 : for(b=clist->bu; b; b=b->prev)
77 : printf(" %d\n", b->bno);
78 : }
79 : */
80 :
81 0 : static int parse_client_data(struct asfd *srfd,
82 : struct cstat *clist, struct conf **confs)
83 : {
84 0 : int ret=0;
85 0 : char *command=NULL;
86 0 : char *client=NULL;
87 0 : char *backup=NULL;
88 0 : char *logfile=NULL;
89 0 : char *browse=NULL;
90 0 : const char *cp=NULL;
91 0 : struct cstat *cstat=NULL;
92 0 : struct bu *bu=NULL;
93 : //printf("got client data: '%s'\n", srfd->rbuf->buf);
94 :
95 0 : cp=srfd->rbuf->buf;
96 :
97 0 : command=get_str(&cp, "j:", 0);
98 0 : client=get_str(&cp, "c:", 0);
99 0 : backup=get_str(&cp, "b:", 0);
100 0 : logfile=get_str(&cp, "l:", 0);
101 0 : browse=get_str(&cp, "p:", 1);
102 :
103 0 : if(command)
104 : {
105 0 : if(!strcmp(command, "pretty-print-on"))
106 : {
107 0 : json_set_pretty_print(1);
108 0 : if(json_send_warn(srfd, "Pretty print on"))
109 : goto error;
110 : }
111 0 : else if(!strcmp(command, "pretty-print-off"))
112 : {
113 0 : json_set_pretty_print(0);
114 0 : if(json_send_warn(srfd, "Pretty print off"))
115 : goto error;
116 : }
117 : else
118 : {
119 0 : if(json_send_warn(srfd, "Unknown command"))
120 : goto error;
121 : }
122 : goto end;
123 : }
124 :
125 0 : if(browse)
126 : {
127 0 : free_w(&logfile);
128 0 : if(!(logfile=strdup_w("manifest", __func__)))
129 : goto error;
130 0 : strip_trailing_slashes(&browse);
131 : }
132 :
133 : //dump_cbno(clist, "pcd");
134 :
135 0 : if(client && *client)
136 : {
137 0 : if(!(cstat=cstat_get_by_name(clist, client)))
138 : {
139 0 : if(json_send_warn(srfd, "Could not find client"))
140 : goto error;
141 : goto end;
142 : }
143 :
144 0 : if(cstat_set_backup_list(cstat))
145 : {
146 0 : if(json_send_warn(srfd, "Could not get backup list"))
147 : goto error;
148 : goto end;
149 :
150 : }
151 : }
152 0 : if(cstat && backup)
153 : {
154 0 : unsigned long bno=0;
155 0 : if(!(bno=strtoul(backup, NULL, 10)))
156 : {
157 0 : if(json_send_warn(srfd, "Could not get backup number"))
158 : goto error;
159 : goto end;
160 : }
161 0 : for(bu=cstat->bu; bu; bu=bu->prev)
162 0 : if(bu->bno==bno) break;
163 :
164 0 : if(!bu)
165 : {
166 0 : if(json_send_warn(srfd, "Backup not found"))
167 : goto error;
168 : goto end;
169 : }
170 : }
171 0 : if(logfile)
172 : {
173 0 : if(strcmp(logfile, "manifest")
174 0 : && strcmp(logfile, "backup")
175 0 : && strcmp(logfile, "restore")
176 0 : && strcmp(logfile, "verify")
177 0 : && strcmp(logfile, "backup_stats")
178 0 : && strcmp(logfile, "restore_stats")
179 0 : && strcmp(logfile, "verify_stats"))
180 : {
181 0 : if(json_send_warn(srfd, "File not supported"))
182 : goto error;
183 : goto end;
184 : }
185 : }
186 : /*
187 : printf("client: %s\n", client?:"");
188 : printf("backup: %s\n", backup?:"");
189 : printf("logfile: %s\n", logfile?:"");
190 : */
191 :
192 0 : if(cstat)
193 : {
194 0 : if(!cstat->run_status)
195 0 : cstat_set_run_status(cstat);
196 : }
197 0 : else for(cstat=clist; cstat; cstat=cstat->next)
198 : {
199 0 : if(!cstat->run_status)
200 0 : cstat_set_run_status(cstat);
201 : }
202 :
203 0 : if(json_send(srfd, clist, cstat, bu, logfile, browse,
204 : get_int(confs[OPT_MONITOR_BROWSE_CACHE])))
205 : goto error;
206 :
207 : goto end;
208 : error:
209 : ret=-1;
210 : end:
211 0 : free_w(&client);
212 0 : free_w(&backup);
213 0 : free_w(&logfile);
214 0 : free_w(&browse);
215 0 : return ret;
216 : }
217 :
218 0 : static int parse_data(struct asfd *asfd, struct cstat *clist,
219 : struct asfd *cfd, struct conf **confs)
220 : {
221 0 : if(asfd==cfd) return parse_client_data(asfd, clist, confs);
222 0 : return parse_parent_data(asfd, clist);
223 : }
224 :
225 : static int have_data_for_running_clients(struct cstat *clist)
226 : {
227 : struct cstat *c;
228 0 : for(c=clist; c; c=c->next)
229 0 : if(c->run_status==RUN_STATUS_RUNNING
230 0 : && c->cntr->cntr_status==CNTR_STATUS_UNSET)
231 : return 0;
232 : return 1;
233 : }
234 :
235 0 : static int get_initial_data(struct async *as,
236 : struct cstat **clist,
237 : struct conf **confs, struct conf **cconfs)
238 : {
239 0 : int x=5;
240 0 : struct asfd *asfd=NULL;
241 :
242 0 : if(cstat_load_data_from_disk(clist, confs, cconfs))
243 : return -1;
244 :
245 : // Try to get the initial data for running clients, but do not
246 : // wait forever.
247 0 : while(x--)
248 : {
249 0 : if(have_data_for_running_clients(*clist))
250 : return 0;
251 0 : if(as->read_write(as))
252 : {
253 0 : logp("Exiting main status server loop\n");
254 0 : return -1;
255 : }
256 0 : asfd=as->asfd->next;
257 0 : if(asfd->rbuf->buf)
258 : {
259 0 : if(parse_data(asfd, *clist, NULL, confs))
260 : {
261 0 : iobuf_free_content(asfd->rbuf);
262 0 : return -1;
263 : }
264 0 : iobuf_free_content(asfd->rbuf);
265 : }
266 : }
267 : return 0;
268 : }
269 :
270 0 : int status_server(struct async *as, struct conf **confs)
271 : {
272 0 : int ret=-1;
273 0 : int gotdata=0;
274 : struct asfd *asfd;
275 0 : struct cstat *clist=NULL;
276 0 : struct asfd *cfd=as->asfd; // Client.
277 0 : struct conf **cconfs=NULL;
278 :
279 0 : if(!(cconfs=confs_alloc()))
280 : goto end;
281 :
282 0 : if(get_initial_data(as, &clist, confs, cconfs))
283 : goto end;
284 :
285 : while(1)
286 : {
287 : // Take the opportunity to get data from the disk if nothing
288 : // was read from the fds.
289 0 : if(gotdata) gotdata=0;
290 0 : else if(cstat_load_data_from_disk(&clist, confs, cconfs))
291 : goto end;
292 0 : if(as->read_write(as))
293 : {
294 0 : logp("Exiting main status server loop\n");
295 : break;
296 : }
297 0 : for(asfd=as->asfd; asfd; asfd=asfd->next)
298 0 : while(asfd->rbuf->buf)
299 : {
300 0 : gotdata=1;
301 0 : if(parse_data(asfd, clist, cfd, confs)
302 0 : || asfd->parse_readbuf(asfd))
303 : goto end;
304 0 : iobuf_free_content(asfd->rbuf);
305 : }
306 : }
307 0 : ret=0;
308 : end:
309 : // FIX THIS: should free clist;
310 0 : return ret;
311 : }
|