54 #define SS_TIMEOUT 300 |
54 #define SS_TIMEOUT 300 |
55 |
55 |
56 #define MAX_INTERVALS 6 |
56 #define MAX_INTERVALS 6 |
57 const int GRAPH_INTERVAL[MAX_INTERVALS] = { 0, 1, 5, 15, 30, 60, }; |
57 const int GRAPH_INTERVAL[MAX_INTERVALS] = { 0, 1, 5, 15, 30, 60, }; |
58 const int GRAPH_DATALINES[MAX_INTERVALS] = { 0, 800, 3200, 12000, 24000, 48000, }; |
58 const int GRAPH_DATALINES[MAX_INTERVALS] = { 0, 800, 3200, 12000, 24000, 48000, }; |
|
59 const char MONTH[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; |
|
60 |
|
61 |
|
62 typedef struct _ls_list { |
|
63 struct _ls_list *next; /* Next record pointer */ |
|
64 char d_name[256]; /* File name */ |
|
65 mode_t mode; /* File mode */ |
|
66 off_t size; /* File size */ |
|
67 time_t mtime; /* File modification time */ |
|
68 } ls_list; |
|
69 |
|
70 |
|
71 |
|
72 void tidy_lslist(ls_list **); |
|
73 void fill_list(ls_list **, char *, mode_t, off_t, time_t); |
|
74 int comp(ls_list **,ls_list **); |
|
75 void sort_list(ls_list **); |
|
76 |
|
77 |
59 |
78 |
60 /* |
79 /* |
61 * Send message to client |
80 * Send message to client |
62 */ |
81 */ |
63 int srv_send(const char *format, ...) |
82 int srv_send(const char *format, ...) |
161 } |
180 } |
162 } else { |
181 } else { |
163 previous = current; |
182 previous = current; |
164 current = current->next; |
183 current = current->next; |
165 } |
184 } |
|
185 } |
|
186 |
|
187 return 0; |
|
188 } |
|
189 |
|
190 |
|
191 |
|
192 void tidy_lslist(ls_list **lap) |
|
193 { |
|
194 ls_list *tmp, *old; |
|
195 |
|
196 for (tmp = *lap; tmp; tmp = old) { |
|
197 old = tmp->next; |
|
198 free(tmp); |
|
199 } |
|
200 *lap = NULL; |
|
201 } |
|
202 |
|
203 |
|
204 |
|
205 void fill_list(ls_list **lap, char *name, mode_t mode, off_t size, time_t mtime) |
|
206 { |
|
207 ls_list **tmp; |
|
208 |
|
209 for (tmp = lap; *tmp; tmp = &((*tmp)->next)); |
|
210 |
|
211 *tmp = (ls_list *)malloc(sizeof(ls_list)); |
|
212 (*tmp)->next = NULL; |
|
213 strncpy((*tmp)->d_name, name, 256); |
|
214 (*tmp)->mode = mode; |
|
215 (*tmp)->size = size; |
|
216 (*tmp)->mtime = mtime; |
|
217 tmp = &((*tmp)->next); |
|
218 } |
|
219 |
|
220 |
|
221 |
|
222 void sort_list(ls_list **lap) |
|
223 { |
|
224 ls_list *ta, **vector; |
|
225 size_t n = 0, i; |
|
226 |
|
227 if (*lap == NULL) |
|
228 return; |
|
229 |
|
230 for (ta = *lap; ta; ta = ta->next) |
|
231 n++; |
|
232 vector = (ls_list **)malloc(n * sizeof(ls_list *)); |
|
233 i = 0; |
|
234 |
|
235 for (ta = *lap; ta; ta = ta->next) { |
|
236 vector[i++] = ta; |
|
237 } |
|
238 qsort(vector, n, sizeof(ls_list *), (int(*)(const void*, const void*))comp); |
|
239 |
|
240 (*lap) = vector[0]; |
|
241 i = 1; |
|
242 |
|
243 for (ta = *lap; ta; ta = ta->next) { |
|
244 if (i < n) |
|
245 ta->next = vector[i++]; |
|
246 else |
|
247 ta->next = NULL; |
|
248 } |
|
249 |
|
250 free(vector); |
|
251 return; |
|
252 } |
|
253 |
|
254 |
|
255 |
|
256 int comp(ls_list **lsp1, ls_list **lsp2) |
|
257 { |
|
258 return strcmp((*lsp1)->d_name, (*lsp2)->d_name); |
|
259 } |
|
260 |
|
261 |
|
262 |
|
263 /* |
|
264 * ARCHIVE DIR |
|
265 * ARCHIVE GET filename |
|
266 * ARCHIVE HELP |
|
267 */ |
|
268 int cmd_archive(char *buf) |
|
269 { |
|
270 char *opt, *param, *name = NULL, *filename = NULL, mbits[11], tstr[24]; |
|
271 DIR *dd; |
|
272 FILE *fp; |
|
273 struct dirent entry, *result; |
|
274 ls_list *lsx = NULL, *tmp; |
|
275 struct stat sbuf; |
|
276 struct tm *tbuf; |
|
277 time_t ftime; |
|
278 |
|
279 opt = strtok(buf, " \0"); |
|
280 opt = strtok(NULL, " \0"); |
|
281 |
|
282 if (opt == NULL) { |
|
283 srv_send((char *)"501 Subcommand missing"); |
|
284 return 1; |
|
285 } |
|
286 param = strtok(NULL, "\0"); |
|
287 |
|
288 if (strcmp(opt, (char *)"HELP") == 0) { |
|
289 srv_send((char *)"100 Help text follows:"); |
|
290 srv_send((char *)"Recognized commands:"); |
|
291 srv_send((char *)"ARCHIVE DIR Archived logfiles directory"); |
|
292 srv_send((char *)"ARCHIVE GET filename Archived logfile download"); |
|
293 srv_send((char *)"."); |
|
294 return 0; |
|
295 } |
|
296 |
|
297 if (strcmp(opt, (char *)"DIR") == 0) { |
|
298 |
|
299 if (getenv((char *)"USER") == NULL) { |
|
300 name = xstrcpy((char *)"/root"); |
|
301 } else { |
|
302 name = xstrcpy(getenv((char *)"HOME")); |
|
303 } |
|
304 name = xstrcat(name, (char *)"/.thermferm/log/"); |
|
305 |
|
306 if ((dd = opendir(name))) { |
|
307 for (;;) { |
|
308 if ((readdir_r(dd, &entry, &result)) != 0) { |
|
309 syslog(LOG_NOTICE, "readdir_r: error=%d", errno); |
|
310 break; |
|
311 } |
|
312 if (result == NULL) /* End of directory */ |
|
313 break; |
|
314 if (result->d_name[0] != '.') { |
|
315 filename = xstrcpy(name); |
|
316 filename = xstrcat(filename, result->d_name); |
|
317 if ((stat(filename, &sbuf)) == 0) { |
|
318 fill_list(&lsx, result->d_name, sbuf.st_mode, sbuf.st_size, sbuf.st_mtime); |
|
319 } |
|
320 free(filename); |
|
321 filename = NULL; |
|
322 } |
|
323 } |
|
324 closedir(dd); |
|
325 } else { |
|
326 syslog(LOG_NOTICE, "opendir: \"%s\" error=%d", name, errno); |
|
327 } |
|
328 |
|
329 sort_list(&lsx); |
|
330 |
|
331 srv_send((char *)"212 Archive directory follows:"); |
|
332 for (tmp = lsx; tmp; tmp = tmp->next) { |
|
333 sprintf(mbits, "----------"); |
|
334 if (tmp->mode & S_IRUSR) |
|
335 mbits[1] = 'r'; |
|
336 if (tmp->mode & S_IWUSR) |
|
337 mbits[2] = 'w'; |
|
338 if (tmp->mode & S_IXUSR) |
|
339 mbits[3] = 'x'; |
|
340 if (tmp->mode & S_IRGRP) |
|
341 mbits[4] = 'r'; |
|
342 if (tmp->mode & S_IWGRP) |
|
343 mbits[5] = 'w'; |
|
344 if (tmp->mode & S_IXGRP) |
|
345 mbits[6] = 'x'; |
|
346 if (tmp->mode & S_IROTH) |
|
347 mbits[7] = 'r'; |
|
348 if (tmp->mode & S_IWOTH) |
|
349 mbits[8] = 'w'; |
|
350 if (tmp->mode & S_IXOTH) |
|
351 mbits[9] = 'x'; |
|
352 ftime = tmp->mtime; |
|
353 tbuf = localtime(&ftime); |
|
354 sprintf(tstr, "%02d %s %04d %02d:%02d", tbuf->tm_mday, MONTH[tbuf->tm_mon], tbuf->tm_year+1900, tbuf->tm_hour, tbuf->tm_min); |
|
355 srv_send((char *)"%s,%s,%d,%s", tmp->d_name, mbits, tmp->size, tstr); |
|
356 } |
|
357 srv_send((char *)"."); |
|
358 tidy_lslist(&lsx); |
|
359 |
|
360 free(name); |
|
361 name = NULL; |
|
362 return 1; |
|
363 } |
|
364 |
|
365 if (param == NULL) { |
|
366 srv_send((char *)"502 Parameter missing"); |
|
367 return 1; |
|
368 } |
|
369 |
|
370 if (strcmp(opt, (char *)"GET") == 0) { |
|
371 if (getenv((char *)"USER") == NULL) { |
|
372 name = xstrcpy((char *)"/root"); |
|
373 } else { |
|
374 name = xstrcpy(getenv((char *)"HOME")); |
|
375 } |
|
376 name = xstrcat(name, (char *)"/.thermferm/log/"); |
|
377 name = xstrcat(name, param); |
|
378 |
|
379 if ((fp = fopen(name, "r"))) { |
|
380 char buffer[256]; |
|
381 |
|
382 srv_send((char *)"212 Archive file follows:"); |
|
383 while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) { |
|
384 int i; |
|
385 |
|
386 for (i = 0; i < strlen(buffer); i++) { |
|
387 if (buffer[i] == '\n') |
|
388 buffer[i] = '\0'; |
|
389 if (buffer[i] == '\r') |
|
390 buffer[i] = '\0'; |
|
391 } |
|
392 srv_send(buffer); |
|
393 } |
|
394 srv_send((char *)"."); |
|
395 fclose(fp); |
|
396 } else { |
|
397 srv_send((char *)"440 No such file"); |
|
398 return 1; |
|
399 } |
|
400 |
|
401 free(name); |
|
402 name = NULL; |
|
403 return 1; |
166 } |
404 } |
167 |
405 |
168 return 0; |
406 return 0; |
169 } |
407 } |
170 |
408 |
2110 } |
2348 } |
2111 |
2349 |
2112 /* |
2350 /* |
2113 * Process commands from the client |
2351 * Process commands from the client |
2114 */ |
2352 */ |
2115 if (strncmp(buf, "DEVICE", 6) == 0) { |
2353 if (strncmp(buf, "ARCHIVE", 7) == 0) { |
|
2354 cmd_archive(buf); |
|
2355 } else if (strncmp(buf, "DEVICE", 6) == 0) { |
2116 if (cmd_device(buf) == 0) |
2356 if (cmd_device(buf) == 0) |
2117 wrconfig(); |
2357 wrconfig(); |
2118 } else if (strncmp(buf, "GLOBAL", 6) == 0) { |
2358 } else if (strncmp(buf, "GLOBAL", 6) == 0) { |
2119 if (cmd_global(buf) == 0) |
2359 if (cmd_global(buf) == 0) |
2120 wrconfig(); |
2360 wrconfig(); |
2121 } else if (strncmp(buf, "HELP", 4) == 0) { |
2361 } else if (strncmp(buf, "HELP", 4) == 0) { |
2122 srv_send((char *)"100 Help text follows"); |
2362 srv_send((char *)"100 Help text follows"); |
2123 srv_send((char *)"Recognized commands:"); |
2363 srv_send((char *)"Recognized commands:"); |
2124 srv_send((char *)""); |
2364 srv_send((char *)""); |
2125 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
2365 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
2366 srv_send((char *)"ARCHIVE DIR Archived logfiles directory"); |
|
2367 srv_send((char *)"ARCHIVE GET filename Archived logfile download"); |
2126 srv_send((char *)"DEVICE ADD type Add new Device type"); |
2368 srv_send((char *)"DEVICE ADD type Add new Device type"); |
2127 srv_send((char *)"DEVICE DEL uuid Delete Device by uuid"); |
2369 srv_send((char *)"DEVICE DEL uuid Delete Device by uuid"); |
2128 srv_send((char *)"DEVICE LIST List Devices"); |
2370 srv_send((char *)"DEVICE LIST List Devices"); |
2129 srv_send((char *)"DEVICE GET uuid Get Device record by uuid"); |
2371 srv_send((char *)"DEVICE GET uuid Get Device record by uuid"); |
2130 srv_send((char *)"DEVICE PUT uuid Put Device record by uuid"); |
2372 srv_send((char *)"DEVICE PUT uuid Put Device record by uuid"); |