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