/************************************************************************** * * EXTINFO.C - Nagios Extended Information CGI * * * License: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/macros.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" static nagios_macros *mac; extern char nagios_process_info[MAX_INPUT_BUFFER]; extern int nagios_process_state; extern int refresh_rate; extern int enable_page_tour; extern int buffer_stats[1][3]; extern int program_stats[MAX_CHECK_STATS_TYPES][3]; extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char url_docs_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char url_js_path[MAX_FILENAME_LENGTH]; extern int enable_splunk_integration; extern char *notes_url_target; extern char *action_url_target; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; #define MAX_MESSAGE_BUFFER 4096 #define HEALTH_WARNING_PERCENTAGE 85 #define HEALTH_CRITICAL_PERCENTAGE 75 /* SORTDATA structure */ typedef struct sortdata_struct { int is_service; servicestatus *svcstatus; hoststatus *hststatus; struct sortdata_struct *next; } sortdata; void document_header(int); void document_footer(void); int process_cgivars(void); void show_process_info(void); void show_host_info(void); void show_service_info(void); void show_all_comments(void); void show_performance_data(void); void show_hostgroup_info(void); void show_servicegroup_info(void); void show_all_downtime(void); void show_scheduling_queue(void); void display_comments(int); int sort_data(int, int); int compare_sortdata_entries(int, int, sortdata *, sortdata *); void free_sortdata_list(void); authdata current_authdata; sortdata *sortdata_list = NULL; char *host_name = ""; char *hostgroup_name = ""; char *servicegroup_name = ""; char *service_desc = ""; int display_type = DISPLAY_PROCESS_INFO; int sort_type = SORT_ASCENDING; int sort_option = SORT_NEXTCHECKTIME; int embedded = FALSE; int display_header = TRUE; int main(void) { int found = FALSE; char temp_buffer[MAX_INPUT_BUFFER] = ""; char *processed_string = NULL; host *temp_host = NULL; hostsmember *temp_parenthost = NULL; hostgroup *temp_hostgroup = NULL; service *temp_service = NULL; servicegroup *temp_servicegroup = NULL; mac = get_global_macros(); /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, READ_ALL_STATUS_DATA); /* initialize macros */ init_macros(); /* get authentication information */ get_authentication_information(¤t_authdata); document_header(TRUE); if(display_header == TRUE) { /* begin top table */ printf("
\n");
if(display_type == DISPLAY_HOST_INFO)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Information");
else if(display_type == DISPLAY_SERVICE_INFO)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Information");
else if(display_type == DISPLAY_COMMENTS)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "All Host and Service Comments");
else if(display_type == DISPLAY_PERFORMANCE)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Performance Information");
else if(display_type == DISPLAY_HOSTGROUP_INFO)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Hostgroup Information");
else if(display_type == DISPLAY_SERVICEGROUP_INFO)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Servicegroup Information");
else if(display_type == DISPLAY_DOWNTIME)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "All Host and Service Scheduled Downtime");
else if(display_type == DISPLAY_SCHEDULING_QUEUE)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Check Scheduling Queue");
else
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Nagios Process Information");
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
display_info_table(temp_buffer, TRUE, ¤t_authdata);
/* find the host */
if(display_type == DISPLAY_HOST_INFO || display_type == DISPLAY_SERVICE_INFO) {
temp_host = find_host(host_name);
grab_host_macros_r(mac, temp_host);
if(display_type == DISPLAY_SERVICE_INFO) {
temp_service = find_service(host_name, service_desc);
grab_service_macros_r(mac, temp_service);
}
/* write some Javascript helper functions */
if(temp_host != NULL) {
printf("\n");
}
}
/* find the hostgroup */
else if(display_type == DISPLAY_HOSTGROUP_INFO) {
temp_hostgroup = find_hostgroup(hostgroup_name);
grab_hostgroup_macros_r(mac, temp_hostgroup);
}
/* find the servicegroup */
else if(display_type == DISPLAY_SERVICEGROUP_INFO) {
temp_servicegroup = find_servicegroup(servicegroup_name);
grab_servicegroup_macros_r(mac, temp_servicegroup);
}
if((display_type == DISPLAY_HOST_INFO && temp_host != NULL) || (display_type == DISPLAY_SERVICE_INFO && temp_host != NULL && temp_service != NULL) || (display_type == DISPLAY_HOSTGROUP_INFO && temp_hostgroup != NULL) || (display_type == DISPLAY_SERVICEGROUP_INFO && temp_servicegroup != NULL)) {
printf("
| \n");
/* middle column of top row */
printf("\n");
if((display_type == DISPLAY_HOST_INFO && temp_host != NULL) || (display_type == DISPLAY_SERVICE_INFO && temp_host != NULL && temp_service != NULL) || (display_type == DISPLAY_HOSTGROUP_INFO && temp_hostgroup != NULL) || (display_type == DISPLAY_SERVICEGROUP_INFO && temp_servicegroup != NULL)) {
if(display_type == DISPLAY_HOST_INFO) {
printf(" Host \n");
printf("%s \n", temp_host->alias);
printf("(%s) \n", temp_host->name); if(temp_host->parent_hosts != NULL) { /* print all parent hosts */ printf(" Parents: \n");
for(temp_parenthost = temp_host->parent_hosts; temp_parenthost != NULL; temp_parenthost = temp_parenthost->next)
printf("\n", STATUS_CGI, url_encode(temp_parenthost->host_name), temp_parenthost->host_name);
printf(""); } printf(" Member of ");
for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == TRUE) {
if(found == TRUE)
printf(", ");
printf("%s", STATUS_CGI, url_encode(temp_hostgroup->group_name), temp_hostgroup->group_name);
found = TRUE;
}
}
if(found == FALSE)
printf("No hostgroups");
printf(" \n"); printf(" %s \n", temp_host->address);
}
if(display_type == DISPLAY_SERVICE_INFO) {
printf("Service %s On Host \n", service_desc);
printf("%s \n", temp_host->alias);
printf("(%s) \n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name), temp_host->name); printf(" Member of ");
for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
if(is_service_member_of_servicegroup(temp_servicegroup, temp_service) == TRUE) {
if(found == TRUE)
printf(", ");
printf("%s", STATUS_CGI, url_encode(temp_servicegroup->group_name), temp_servicegroup->group_name);
found = TRUE;
}
}
if(found == FALSE)
printf("No servicegroups.");
printf(" \n"); printf(" %s \n", temp_host->address);
}
if(display_type == DISPLAY_HOSTGROUP_INFO) {
printf("Hostgroup \n");
printf("%s \n", temp_hostgroup->alias);
printf("(%s) \n", temp_hostgroup->group_name);
if(temp_hostgroup->notes != NULL) {
process_macros_r(mac, temp_hostgroup->notes, &processed_string, 0);
printf("%s ", processed_string); free(processed_string); } } if(display_type == DISPLAY_SERVICEGROUP_INFO) { printf("Servicegroup \n");
printf("%s \n", temp_servicegroup->alias);
printf("(%s) \n", temp_servicegroup->group_name);
if(temp_servicegroup->notes != NULL) {
process_macros_r(mac, temp_servicegroup->notes, &processed_string, 0);
printf("%s ", processed_string); free(processed_string); } } if(display_type == DISPLAY_SERVICE_INFO) { if(temp_service->icon_image != NULL) { printf("", (temp_service->icon_image_alt == NULL) ? "" : temp_service->icon_image_alt, (temp_service->icon_image_alt == NULL) ? "" : temp_service->icon_image_alt); } if(temp_service->icon_image_alt != NULL) printf("( %s )\n", temp_service->icon_image_alt); if(temp_service->notes != NULL) { process_macros_r(mac, temp_service->notes, &processed_string, 0); printf(" %s \n", processed_string); free(processed_string); } } if(display_type == DISPLAY_HOST_INFO) { if(temp_host->icon_image != NULL) { printf("", (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); } if(temp_host->icon_image_alt != NULL) printf("( %s )\n", temp_host->icon_image_alt); if(temp_host->notes != NULL) { process_macros_r(mac, temp_host->notes, &processed_string, 0); printf(" %s \n", processed_string); free(processed_string); } } } printf(" | \n");
/* right column of top row */
printf("\n"); if(display_type == DISPLAY_HOST_INFO && temp_host != NULL) { printf(" | \n"); /* end of top table */ printf("
\n");
printf(" Process Information \n");
printf("
| \n");
printf(" Process Commands \n");
printf("
|
\n");
printf(" Host State Information \n");
if(temp_hoststatus->has_been_checked == FALSE)
printf("This host has not yet been checked, so status information is not available. \n");
else {
printf("
| \n");
printf("\n");
printf("
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\n"); /* display comments */ display_comments(HOST_COMMENT); printf(" | \n"); printf("
\n");
printf(" Service State Information \n");
if(temp_svcstatus->has_been_checked == FALSE)
printf("This service has not yet been checked, so status information is not available. \n");
else {
printf("
| \n");
printf("\n");
printf("
| \n");
printf("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\n"); /* display comments */ display_comments(SERVICE_COMMENT); printf(" | \n"); printf("
\n"); /* right top panel */ printf(" | \n");
printf(" Hostgroup Commands \n");
if(nagios_process_state == STATE_OK && is_authorized_for_read_only(¤t_authdata) == FALSE) {
printf("
Your account does not have permissions to execute commands. \n"); } else { printf(" It appears as though Nagios is not running, so commands are temporarily unavailable... \n", EXTINFO_CGI, DISPLAY_PROCESS_INFO);
}
printf("\n"); printf("Click here to view Nagios process information | |||||||||||||||||
\n"); printf(" |
\n"); /* right top panel */ printf(" | \n");
printf(" Servicegroup Commands \n");
if(nagios_process_state == STATE_OK) {
printf("
It appears as though Nagios is not running, so commands are temporarily unavailable... \n", EXTINFO_CGI, DISPLAY_PROCESS_INFO);
}
printf("\n"); printf("Click here to view Nagios process information | |||||||||||||||||
\n"); printf(" |
Host Name | Entry Time | Author | Comment | Comment ID | Persistent | Type | Expires | Actions |
---|---|---|---|---|---|---|---|---|
Host Name | Entry Time | Author | Comment | Comment ID | Persistent | Type | Expires | |
%s | ", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_comment->host_name), temp_comment->host_name); printf("%s | %s | %s | %ld | %s | %s | %s | ", bg_class, date_time, bg_class, temp_comment->author, bg_class, temp_comment->comment_data, bg_class, temp_comment->comment_id, bg_class, (temp_comment->persistent) ? "Yes" : "No", bg_class, comment_type, bg_class, (temp_comment->expires == TRUE) ? expire_time : "N/A"); if(is_authorized_for_read_only(¤t_authdata)==FALSE) printf("", COMMAND_CGI, CMD_DEL_HOST_COMMENT, temp_comment->comment_id, url_images_path, DELETE_ICON); printf(" |
There are no host comments |
Host Name | Service | Entry Time | Author | Comment | Comment ID | Persistent | Type | Expires | Actions |
---|---|---|---|---|---|---|---|---|---|
Host Name | Service | Entry Time | Author | Comment | Comment ID | Persistent | Type | Expires | |
%s | ", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_comment->host_name), temp_comment->host_name); printf("%s | ", url_encode(temp_comment->service_description), temp_comment->service_description); printf("%s | %s | %s | %ld | %s | %s | %s | ", bg_class, date_time, bg_class, temp_comment->author, bg_class, temp_comment->comment_data, bg_class, temp_comment->comment_id, bg_class, (temp_comment->persistent) ? "Yes" : "No", bg_class, comment_type, bg_class, (temp_comment->expires == TRUE) ? expire_time : "N/A"); if(is_authorized_for_read_only(¤t_authdata)==FALSE) printf("", COMMAND_CGI, CMD_DEL_SVC_COMMENT, temp_comment->comment_id, url_images_path, DELETE_ICON); printf(" |
There are no service comments |
Services Actively Checked: | \n");
printf("\n");
/* fake this so we don't divide by zero for just showing the table */
if(total_active_service_checks == 0)
total_active_service_checks = 1;
printf("
| \n");
printf("
| \n");
printf("|||||||||||||||||||||||||||||||||||||||||||||||||
Services Passively Checked: | \n");
printf("\n");
/* fake this so we don't divide by zero for just showing the table */
if(total_passive_service_checks == 0)
total_passive_service_checks = 1;
printf("
| \n");
printf("
| \n");
printf("|||||||||||||||||||||||||||||||||||||||||||||||||
Hosts Actively Checked: | \n");
printf("\n");
/* fake this so we don't divide by zero for just showing the table */
if(total_active_host_checks == 0)
total_active_host_checks = 1;
printf("
| \n");
printf("
| \n");
printf("|||||||||||||||||||||||||||||||||||||||||||||||||
Hosts Passively Checked: | \n");
printf("\n");
/* fake this so we don't divide by zero for just showing the table */
if(total_passive_host_checks == 0)
total_passive_host_checks = 1;
printf("
| \n");
printf("
| \n");
printf("|||||||||||||||||||||||||||||||||||||||||||||||||
Check Statistics: | \n");
printf("\n");
printf("
| \n");
printf("||||||||||||||||||||||||||||||||||||||||||||||||||
Buffer Usage: | \n");
printf("\n");
printf("
| \n");
printf("
", url_images_path, COMMENT_ICON); if(type == HOST_COMMENT) printf("", COMMAND_CGI, CMD_ADD_HOST_COMMENT, url_encode(host_name)); else { printf("", url_encode(service_desc)); } printf("Add a new comment | \n"); printf("", url_images_path, DELETE_ICON); if(type == HOST_COMMENT) printf("", COMMAND_CGI, CMD_DEL_ALL_HOST_COMMENTS, url_encode(host_name)); else { printf("", url_encode(service_desc)); } printf("Delete all comments | \n"); printf("
Host Name | Entry Time | Author | Comment | Start Time | End Time | Type | Duration | Downtime ID | Trigger ID | Actions |
---|---|---|---|---|---|---|---|---|---|---|
%s | ", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_downtime->host_name), temp_downtime->host_name); get_time_string(&temp_downtime->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bg_class, date_time); printf("%s | ", bg_class, (temp_downtime->author == NULL) ? "N/A" : temp_downtime->author); printf("%s | ", bg_class, (temp_downtime->comment == NULL) ? "N/A" : temp_downtime->comment); get_time_string(&temp_downtime->start_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bg_class, date_time); get_time_string(&temp_downtime->end_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bg_class, date_time); printf("%s | ", bg_class, (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible"); get_time_breakdown(temp_downtime->duration, &days, &hours, &minutes, &seconds); printf("%dd %dh %dm %ds | ", bg_class, days, hours, minutes, seconds); printf("%lu | ", bg_class, temp_downtime->downtime_id); printf("", bg_class); if(temp_downtime->triggered_by == 0) printf("N/A"); else printf("%lu", temp_downtime->triggered_by); printf(" | \n"); printf("", COMMAND_CGI, CMD_DEL_HOST_DOWNTIME, temp_downtime->downtime_id, url_images_path, DELETE_ICON); printf(" |
There are no hosts with scheduled downtime |
Host Name | Service | Entry Time | Author | Comment | Start Time | End Time | Type | Duration | Downtime ID | Trigger ID | Actions |
---|---|---|---|---|---|---|---|---|---|---|---|
%s | ", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_downtime->host_name), temp_downtime->host_name); printf("%s | ", url_encode(temp_downtime->service_description), temp_downtime->service_description); get_time_string(&temp_downtime->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bg_class, date_time); printf("%s | ", bg_class, (temp_downtime->author == NULL) ? "N/A" : temp_downtime->author); printf("%s | ", bg_class, (temp_downtime->comment == NULL) ? "N/A" : temp_downtime->comment); get_time_string(&temp_downtime->start_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bg_class, date_time); get_time_string(&temp_downtime->end_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bg_class, date_time); printf("%s | ", bg_class, (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible"); get_time_breakdown(temp_downtime->duration, &days, &hours, &minutes, &seconds); printf("%dd %dh %dm %ds | ", bg_class, days, hours, minutes, seconds); printf("%lu | ", bg_class, temp_downtime->downtime_id); printf("", bg_class); if(temp_downtime->triggered_by == 0) printf("N/A"); else printf("%lu", temp_downtime->triggered_by); printf(" | \n"); printf("", COMMAND_CGI, CMD_DEL_SVC_DOWNTIME, temp_downtime->downtime_id, url_images_path, DELETE_ICON); printf(" |
There are no services with scheduled downtime |
\n"); printf("
Host | ", temp_url, SORT_ASCENDING, SORT_HOSTNAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_HOSTNAME, url_images_path, DOWN_ARROW_ICON); printf("Service | ", temp_url, SORT_ASCENDING, SORT_SERVICENAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_SERVICENAME, url_images_path, DOWN_ARROW_ICON); printf("Last Check | ", temp_url, SORT_ASCENDING, SORT_LASTCHECKTIME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_LASTCHECKTIME, url_images_path, DOWN_ARROW_ICON); printf("Next Check | ", temp_url, SORT_ASCENDING, SORT_NEXTCHECKTIME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_NEXTCHECKTIME, url_images_path, DOWN_ARROW_ICON); printf("Type | Active Checks | Actions | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
%s | ", bgclass, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_svcstatus->host_name), temp_svcstatus->host_name); printf("%s | ", url_encode(temp_svcstatus->description), temp_svcstatus->description); get_time_string(&temp_svcstatus->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bgclass, (temp_svcstatus->last_check == (time_t)0) ? "N/A" : date_time); get_time_string(&temp_svcstatus->next_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bgclass, (temp_svcstatus->next_check == (time_t)0) ? "N/A" : date_time); printf("", bgclass); if(temp_svcstatus->check_options == CHECK_OPTION_NONE) printf("Normal "); else { if(temp_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION) printf("Forced "); if(temp_svcstatus->check_options & CHECK_OPTION_FRESHNESS_CHECK) printf("Freshness "); if(temp_svcstatus->check_options & CHECK_OPTION_ORPHAN_CHECK) printf("Orphan "); } printf(" | "); printf("%s | ", (temp_svcstatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_svcstatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED"); printf("", bgclass); if(temp_svcstatus->checks_enabled == TRUE) { printf("\n", url_encode(temp_svcstatus->description), url_images_path, DISABLED_ICON); } else { printf("\n", url_encode(temp_svcstatus->description), url_images_path, ENABLED_ICON); } printf("\n", url_encode(temp_svcstatus->description), (temp_svcstatus->checks_enabled == TRUE) ? "&force_check" : "", url_images_path, DELAY_ICON); printf(" | \n"); } /* get the host status */ else { printf("%s | ", bgclass, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hststatus->host_name), temp_hststatus->host_name); printf("", bgclass); get_time_string(&temp_hststatus->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf(" | %s | ", bgclass, (temp_hststatus->last_check == (time_t)0) ? "N/A" : date_time); get_time_string(&temp_hststatus->next_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); printf("%s | ", bgclass, (temp_hststatus->next_check == (time_t)0) ? "N/A" : date_time); printf("", bgclass); if(temp_hststatus->check_options == CHECK_OPTION_NONE) printf("Normal "); else { if(temp_hststatus->check_options & CHECK_OPTION_FORCE_EXECUTION) printf("Forced "); if(temp_hststatus->check_options & CHECK_OPTION_FRESHNESS_CHECK) printf("Freshness "); if(temp_hststatus->check_options & CHECK_OPTION_ORPHAN_CHECK) printf("Orphan "); } printf(" | "); printf("%s | ", (temp_hststatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_hststatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED"); printf("", bgclass); if(temp_hststatus->checks_enabled == TRUE) { printf("\n", url_images_path, DISABLED_ICON); } else { printf("\n", url_images_path, ENABLED_ICON); } printf("\n", url_images_path, DELAY_ICON); printf(" | \n"); } printf("