2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief target(collector)
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-07-06 SM
42 #include <sys/types.h>
54 #define SEP_LINE "-----------------------------------------------------------------------------------------"
58 * @retval 0 - time1 <= time2, time1 is same or old
59 * @retval 1 - time1 > time2 time1 is new
61 int cmpDateTime(PTS_DateTime *time1, PTS_DateTime *time2) {
101 * select UUID dir, e.g. 12877946-0682-11e0-b442-001f160c9c28
106 static int selectUuidDir(const struct dirent *entry) {
113 if (0 == strcmp(".", entry->d_name)) return 0;
114 if (0 == strcmp("..", entry->d_name)) return 0;
116 /* skip bad dir name - by length */
117 len = strlen(entry->d_name);
118 // TODO ("UUID dirname len = %d, %s\n",len, entry->d_name);
119 if (len != 36) return 0;
121 // TODO not enough?, add test cases for the bad dir name
124 // TODO check the format
126 if (0 != stat(entry->d_name, &buffer)) return 0;
127 if (S_ISDIR(buffer.st_mode)) return 1;
129 if (entry->d_type == DT_DIR) return 1;
138 * CONFDIR/UUID/rmX.xml
143 * conf->current_rm_uuid
146 * @retval PTS_SUCCESS
147 * @retval PTS_INTERNAL_ERROR
149 int getRmList(OPENPTS_CONFIG *conf, char * config_dir) {
152 struct dirent **dir_list;
157 PTS_DateTime *tmp_time;
161 OPENPTS_RMSET *rmset;
162 OPENPTS_RMSET *rmset1;
163 OPENPTS_RMSET *rmset2;
165 // printf("Show RMs by UUID\n");
166 // printf("config dir : %s\n", config_dir);
168 /* move to config dir */
169 if ((chdir(conf->config_dir)) != 0) {
170 fprintf(stderr, "Accessing config directory %s\n", conf->config_dir);
171 return PTS_INTERNAL_ERROR;
175 dir_num = scandir(".", &dir_list, &selectUuidDir, NULL);
176 if ( dir_num == -1 ) {
177 fprintf(stderr, "no target data\n");
178 return PTS_INTERNAL_ERROR;
182 // TODO alloc 1 more RMSET for update
183 conf->rmsets = (OPENPTS_RMSETS *) malloc(sizeof(OPENPTS_RMSETS) + sizeof(OPENPTS_RMSET) * (dir_num + 1) );
184 if (conf->rmsets == NULL) {
186 return PTS_INTERNAL_ERROR;
188 conf->rmsets->rmset_num = dir_num;
191 for (cnt = 0; cnt < dir_num; cnt++) {
192 rmset = &conf->rmsets->rmset[cnt];
194 ERROR("no memory cnt=%d\n", cnt);
195 return PTS_INTERNAL_ERROR;
197 rmset->str_uuid = smalloc(dir_list[cnt]->d_name);
198 rmset->uuid = getUuidFromString(dir_list[cnt]->d_name);
199 rmset->time = getDateTimeOfUuid(rmset->uuid);
200 rmset->state = OPENPTS_RM_STATE_UNKNOWN;
201 rmset->dir = getFullpathName(conf->config_dir, rmset->str_uuid);
204 if (conf->rm_uuid->str != NULL) {
205 /* check new RM 1st */
206 if (conf->newrm_uuid != NULL) {
207 if (conf->newrm_uuid->str != NULL) {
208 if (strcmp(conf->newrm_uuid->str, rmset->str_uuid) == 0) {
209 rmset->state = OPENPTS_RM_STATE_NEW;
214 /* check current RM */
215 if (strcmp(conf->rm_uuid->str, rmset->str_uuid) == 0) {
216 /* overrite if newrm = rm */
217 // TODO ("HIT %s\n", conf->str_rm_uuid);
218 rmset->state = OPENPTS_RM_STATE_NOW;
227 for (i = 0; i< dir_num - 1; i++) {
228 for (j = dir_num - 1; j > i; j--) {
229 // printf("i=%d, j=%d\n",i,j);
230 rmset1 = &conf->rmsets->rmset[j-1];
231 rmset2 = &conf->rmsets->rmset[j];
232 if (cmpDateTime(rmset1->time, rmset2->time) > 0) {
233 // printf("%d <-> %d\n", j-1, j);
235 tmp_str_uuid = rmset2->str_uuid;
236 tmp_uuid = rmset2->uuid;
237 tmp_time = rmset2->time;
238 tmp_state = rmset2->state;
239 tmp_dir = rmset2->dir;
241 rmset2->str_uuid = rmset1->str_uuid;
242 rmset2->uuid = rmset1->uuid;
243 rmset2->time = rmset1->time;
244 rmset2->state = rmset1->state;
245 rmset2->dir = rmset1->dir;
247 rmset1->str_uuid = tmp_str_uuid;
248 rmset1->uuid = tmp_uuid;
249 rmset1->time = tmp_time;
250 rmset1->state = tmp_state;
251 rmset1->dir = tmp_dir;
254 // printRmList(conf);
258 conf->rmsets->current_id = 0;
259 for (i = 0; i< dir_num; i++) {
260 rmset = &conf->rmsets->rmset[i];
261 if (rmset->state == OPENPTS_RM_STATE_NOW) {
262 conf->rmsets->current_id = i;
266 /* set old flag id < current_id */
267 for (i = 0; i< conf->rmsets->current_id; i++) {
268 rmset = &conf->rmsets->rmset[i];
269 rmset->state = OPENPTS_RM_STATE_OLD;
273 conf->rmsets->update_id = 9999; // TODO
274 for (i = conf->rmsets->current_id+1; i< dir_num; i++) {
275 rmset = &conf->rmsets->rmset[i];
276 if (rmset->state == OPENPTS_RM_STATE_NEW) {
277 conf->rmsets->update_id = i;
281 /* set trash flag id < current_id */
282 for (i = conf->rmsets->current_id + 1; i< dir_num && i < conf->rmsets->update_id; i++) {
283 rmset = &conf->rmsets->rmset[i];
284 rmset->state = OPENPTS_RM_STATE_TRASH;
294 int rmRmsetDir(char * dir) {
298 // DEBUG("rm -r %s\n", dir);
299 snprintf(buf, BUF_SIZE, "rm -r %s\n", dir);
302 DEBUG("rmRmsetDir() - system failed, %s\n", buf);
312 * @retval PTS_SUCCESS
313 * @retval PTS_OS_ERROR
315 int purgeRenewedRm(OPENPTS_CONFIG *conf) {
319 OPENPTS_RMSET *rmset;
321 int rc2 = PTS_SUCCESS;
323 num = conf->rmsets->rmset_num;
326 for (cnt = 0; cnt < num; cnt++) {
327 rmset = &conf->rmsets->rmset[cnt];
328 state = rmset->state;
330 if (state == OPENPTS_RM_STATE_TRASH) {
331 printf(" purge %s\n", rmset->str_uuid);
332 rc = rmRmsetDir(rmset->dir);
333 if (rc != PTS_SUCCESS) {
342 void printRmList(OPENPTS_CONFIG *conf, char *indent) {
346 OPENPTS_RMSET *rmset;
352 ERROR(" conf is NULL");
355 if (conf->rmsets == NULL) {
356 ERROR(" conf->rmsets is NULL");
361 num = conf->rmsets->rmset_num;
363 printf("%s ID UUID date(UTC) status\n", indent);
364 printf("%s%s\n", indent, SEP_LINE);
367 for (cnt = 0; cnt < num; cnt++) {
368 rmset = &conf->rmsets->rmset[cnt];
370 str_uuid = rmset->str_uuid;
372 state = rmset->state;
374 printf("%s %3d %s %04d-%02d-%02d-%02d:%02d:%02d",
385 if (state == OPENPTS_RM_STATE_OLD) {
387 } else if (state == OPENPTS_RM_STATE_NOW) {
389 } else if (state == OPENPTS_RM_STATE_NEW) { // TODO def name is not clear
390 printf(" NEW (for next boot)\n");
391 } else if (state == OPENPTS_RM_STATE_TRASH) {
392 printf(" RENEWED (-R to purge)\n");
394 printf(" state=UNKNOWN\n");
397 printf("%s%s\n", indent, SEP_LINE);
405 * list/get target list at HOME/.openpts
408 * Setup all entries of target_conf
409 * Does performance issue exist, if we manage large num of targets?
412 * @retval PTS_SUCCESS
413 * @retval PTS_INTERNAL_ERROR
415 int getTargetList(OPENPTS_CONFIG *conf, char * config_dir) {
418 struct dirent **dir_list;
419 OPENPTS_TARGET *target;
420 OPENPTS_CONFIG *target_conf;
423 DEBUG("getTargetList() : %s\n", config_dir);
426 if (conf->target_list != NULL) {
427 ERROR("conf->target_list exist\n");
430 /* move to config dir */
431 if ((chdir(conf->config_dir)) != 0) {
432 fprintf(stderr, "Accessing config directory %s\n", conf->config_dir);
433 return PTS_INTERNAL_ERROR;
437 dir_num = scandir(".", &dir_list, &selectUuidDir, NULL);
438 if ( dir_num == -1 ) {
439 fprintf(stderr, "no target data\n");
440 return PTS_INTERNAL_ERROR;
443 /* malloc target_list */
444 conf->target_list = newTargetList(dir_num + 1); // conf.c
445 if (conf->target_list == NULL) {
447 return PTS_INTERNAL_ERROR;
451 for (cnt = 0; cnt < dir_num; cnt++) {
452 target = &conf->target_list->target[cnt];
453 if (target == NULL) {
454 ERROR("no memory cnt=%d\n", cnt);
455 return PTS_INTERNAL_ERROR;
458 target->str_uuid = smalloc(dir_list[cnt]->d_name);
459 target->uuid = getUuidFromString(dir_list[cnt]->d_name);
460 target->time = getDateTimeOfUuid(target->uuid);
461 target->dir = getFullpathName(conf->config_dir, target->str_uuid);
462 target->target_conf_filename = getFullpathName(target->dir, "target.conf");
464 DEBUG("target conf[%3d] : %s\n", cnt, target->target_conf_filename);
466 /* read target config */
467 target_conf = (void *)newPtsConfig();
468 if (target_conf == NULL) {
469 printf("no memory\n");
470 return PTS_INTERNAL_ERROR; // TODO
472 readTargetConf(target_conf, target->target_conf_filename);
474 /* set collector UUID */
475 target_conf->uuid = newOpenptsUuid2(target->uuid);
477 /* set RM UUID (Mandatory) */
478 rc = readOpenptsUuidFile(target_conf->rm_uuid);
479 if (rc != PTS_SUCCESS) {
480 ERROR("getTargetList() - readOpenptsUuidFile() fail rc=%d\n", rc);
481 freeOpenptsUuid(target_conf->rm_uuid);
482 target_conf->rm_uuid = NULL;
483 return PTS_INTERNAL_ERROR;
486 /* set New RM UUID (Optional) */
487 rc = readOpenptsUuidFile(target_conf->newrm_uuid);
488 if (rc != PTS_SUCCESS) {
489 DEBUG("getTargetList() - readOpenptsUuidFile() fail rc=%d\n", rc);
490 freeOpenptsUuid(target_conf->newrm_uuid);
491 target_conf->newrm_uuid = NULL;
494 /* set Old RM UUID (Optional) */
495 rc = readOpenptsUuidFile(target_conf->oldrm_uuid);
496 if (rc != PTS_SUCCESS) {
497 DEBUG("getTargetList() - readOpenptsUuidFile() fail rc=%d\n", rc);
498 freeOpenptsUuid(target_conf->oldrm_uuid);
499 target_conf->oldrm_uuid = NULL;
502 target->target_conf = (void *)target_conf;
512 * look up the yarget by the hostname.
513 * get the target in target_list which hostname is conf->hostname (given)
515 * openpts, standalone verifier only?
519 char *getTargetConfDir(OPENPTS_CONFIG *conf) {
522 OPENPTS_TARGET *target;
523 OPENPTS_CONFIG *target_conf;
528 ERROR("getTargetConfDir() - conf is NULL\n");
531 if (conf->hostname == NULL) {
532 ERROR("getTargetConfDir() - conf->hostname is NULL\n");
535 if (conf->target_list == NULL) {
536 ERROR("getTargetConfDir() - conf->target_list is NULL\n");
540 /* how many targets? */
541 num = conf->target_list->target_num;
543 /* find the name in the target list */
544 for (cnt = 0; cnt < num; cnt++) {
545 target = &conf->target_list->target[cnt];
546 target_conf = (OPENPTS_CONFIG *) target->target_conf;
548 if (target_conf->hostname == NULL) {
549 DEBUG("hostname is missing in %s\n", target->target_conf_filename);
551 if (!strcmp(conf->hostname, target_conf->hostname)) {
552 /* HIT, return first one, if multiple host was exist conf dir was broken */
553 dir = smalloc(target->dir);
563 * get the target in target_list which hostname is conf->hostname (given)
565 * @return OPENPTS_TARGET
567 OPENPTS_TARGET *getTargetCollector(OPENPTS_CONFIG *conf) {
569 OPENPTS_TARGET *target;
570 OPENPTS_CONFIG *target_conf;
573 num = conf->target_list->target_num;
576 for (cnt = 0; cnt < num; cnt++) {
577 target = &conf->target_list->target[cnt];
578 target_conf = (OPENPTS_CONFIG *) target->target_conf;
580 if (target_conf != NULL) {
581 if (target_conf->hostname == NULL) {
582 DEBUG("hostname is missing in %s\n", target->target_conf_filename);
584 if (!strcmp(conf->hostname, target_conf->hostname)) {
601 * print target list, target par line
603 void printTargetList(OPENPTS_CONFIG *conf, char *indent) {
606 OPENPTS_TARGET *target;
607 OPENPTS_CONFIG *target_conf;
608 char * str_uuid = "N/A";
611 num = conf->target_list->target_num;
614 "date(UTC) username@hostname:port\n",
616 printf("%s%s\n", indent, SEP_LINE);
619 for (cnt = 0; cnt < num; cnt++) {
620 target = &conf->target_list->target[cnt];
621 target_conf = (OPENPTS_CONFIG *) target->target_conf;
625 if (target_conf != NULL) {
626 if (target_conf->uuid != NULL) {
627 if (target_conf->uuid->str != NULL) {
628 str_uuid = target_conf->uuid->str;
631 printf("%s %4d %s %04d-%02d-%02d-%02d:%02d:%02d %s@%s:%s\n",
641 target_conf->ssh_username ? target_conf->ssh_username : "default",
642 target_conf->hostname,
643 target_conf->ssh_port ? target_conf->ssh_port : "default");
648 printf("%s%s\n", indent, SEP_LINE);