/* * callbacks.c - Part of AFD, an automatic file distribution program. * Copyright (c) 2007 - 2015 Holger Kiehl * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 "afddefs.h" DESCR__S_M3 /* ** NAME ** callbacks - all callback functions for module handle_event ** ** SYNOPSIS ** void close_button(Widget w, XtPointer client_data, XtPointer call_data) ** void radio_button(Widget w, XtPointer client_data, XtPointer call_data) ** void set_button(Widget w, XtPointer client_data, XtPointer call_data) ** void toggle_button(Widget w, XtPointer client_data, XtPointer call_data) ** ** DESCRIPTION ** ** RETURN VALUES ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 24.06.2007 H.Kiehl Created ** 18.02.2015 H.Kiehl Use statusbox for information instead of popups ** which have to be acknowledged. ** */ DESCR__E_M3 #include #include /* exit(), malloc(), free() */ #include /* strlen() */ #include #include #include #include #include "handle_event.h" /* External global variables. */ extern Widget end_time_w, entertime_w, start_time_w, statusbox_w, text_w; extern int acknowledge_type, fra_fd, fsa_fd, no_of_alias, no_of_dirs, no_of_hosts; extern time_t end_time_val, start_time_val; extern char **dir_alias, **host_alias, user[]; extern struct filetransfer_status *fsa; extern struct fileretrieve_status *fra; /*########################### close_button() ############################*/ void close_button(Widget w, XtPointer client_data, XtPointer call_data) { exit(0); } /*########################### toggle_button() ###########################*/ void toggle_button(Widget w, XtPointer client_data, XtPointer call_data) { if (XmToggleButtonGetState(w) == True) { XtSetSensitive(entertime_w, True); XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP); } else { XtSetSensitive(entertime_w, False); } return; } /*############################# save_input() ############################*/ void save_input(Widget w, XtPointer client_data, XtPointer call_data) { XT_PTR_TYPE type = (XT_PTR_TYPE)client_data; char *value = XmTextGetString(w); switch (type) { case START_TIME_NO_ENTER : if (value[0] == '\0') { start_time_val = -1; } else if (eval_time(value, w, &start_time_val, START_TIME) < 0) { show_message(statusbox_w, TIME_FORMAT); XtFree(value); return; } reset_message(statusbox_w); break; case START_TIME : if (eval_time(value, w, &start_time_val, START_TIME) < 0) { show_message(statusbox_w, TIME_FORMAT); } else { reset_message(statusbox_w); XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP); } break; case END_TIME_NO_ENTER : if (value[0] == '\0') { end_time_val = -1; } else if (eval_time(value, w, &end_time_val, END_TIME) < 0) { show_message(statusbox_w, TIME_FORMAT); XtFree(value); return; } reset_message(statusbox_w); break; case END_TIME : if (eval_time(value, w, &end_time_val, END_TIME) < 0) { show_message(statusbox_w, TIME_FORMAT); } else { reset_message(statusbox_w); XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP); } break; default : (void)fprintf(stderr, "ERROR : Impossible! (%s %d)\n", __FILE__, __LINE__); exit(INCORRECT); } XtFree(value); return; } /*############################ set_button() #############################*/ void set_button(Widget w, XtPointer client_data, XtPointer call_data) { int flags_changed, flags_unchangeable, i, not_enough_errors, pos; unsigned int event_action; char buffer[256], *reason_str = NULL, *text; if ((text = XmTextGetString(text_w))) { if (text[0] != '\0') { size_t length; length = strlen(text); if ((reason_str = malloc((3 * length))) == NULL) { (void)fprintf(stderr, "malloc() error : %s\n", strerror(errno)); exit(INCORRECT); } else { int j = 0; for (i = 0; i < length; i++) { if (text[i] >= ' ') { if (text[i] == '%') { reason_str[j++] = text[i]; j += sprintf(&reason_str[j], "%02x", (int)text[i]); } else { reason_str[j++] = text[i]; } } else { reason_str[j++] = '%'; j += sprintf(&reason_str[j], "%02x", (int)text[i]); } } reason_str[j] = '\0'; } } XtFree(text); } flags_changed = flags_unchangeable = not_enough_errors = 0; for (i = 0; i < no_of_alias; i++) { event_action = 0; if (fra_fd == -1) { pos = get_host_position(fsa, host_alias[i], no_of_hosts); if (pos == INCORRECT) { (void)fprintf(stderr, "Failed to locate `%s' in FSA.", host_alias[i]); } else { int flag_changed = NO; if ((fsa[pos].error_counter > 0) || ((start_time_val != -1) && (start_time_val != end_time_val)) || (acknowledge_type == UNSET_SELECT)) { if (acknowledge_type == ACKNOWLEDGE_SELECT) { if (start_time_val == -1) { if ((fsa[pos].host_status & HOST_ERROR_ACKNOWLEDGED) == 0) { #ifdef LOCK_DEBUG lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif fsa[pos].host_status |= HOST_ERROR_ACKNOWLEDGED; #ifdef LOCK_DEBUG unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif flag_changed = YES; flags_changed++; } else { flags_unchangeable++; } } else { if ((fsa[pos].host_status & HOST_ERROR_ACKNOWLEDGED_T) == 0) { #ifdef LOCK_DEBUG lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif fsa[pos].host_status |= HOST_ERROR_ACKNOWLEDGED_T; #ifdef LOCK_DEBUG unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif fsa[pos].start_event_handle = start_time_val; fsa[pos].end_event_handle = end_time_val; flag_changed = YES; flags_changed++; } else { flags_unchangeable++; } } event_action = EA_ACKNOWLEDGE; } else if (acknowledge_type == OFFLINE_SELECT) { if (start_time_val == -1) { if ((fsa[pos].host_status & HOST_ERROR_OFFLINE) == 0) { #ifdef LOCK_DEBUG lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif fsa[pos].host_status |= HOST_ERROR_OFFLINE; #ifdef LOCK_DEBUG unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif flag_changed = YES; flags_changed++; } else { flags_unchangeable++; } } else { if ((fsa[pos].host_status & HOST_ERROR_OFFLINE_T) == 0) { #ifdef LOCK_DEBUG lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif fsa[pos].host_status |= HOST_ERROR_OFFLINE_T; #ifdef LOCK_DEBUG unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif fsa[pos].start_event_handle = start_time_val; fsa[pos].end_event_handle = end_time_val; flag_changed = YES; flags_changed++; } else { flags_unchangeable++; } } event_action = EA_OFFLINE; } else /* Unset all the flags. */ { #ifdef LOCK_DEBUG lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else lock_region_w(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif if (fsa[pos].host_status & HOST_ERROR_OFFLINE) { fsa[pos].host_status &= ~HOST_ERROR_OFFLINE; flag_changed = YES; } if (fsa[pos].host_status & HOST_ERROR_ACKNOWLEDGED) { fsa[pos].host_status &= ~HOST_ERROR_ACKNOWLEDGED; flag_changed = YES; } if (fsa[pos].host_status & HOST_ERROR_OFFLINE_T) { fsa[pos].host_status &= ~HOST_ERROR_OFFLINE_T; fsa[pos].start_event_handle = 0L; fsa[pos].end_event_handle = 0L; flag_changed = YES; } if (fsa[pos].host_status & HOST_ERROR_ACKNOWLEDGED_T) { fsa[pos].host_status &= ~HOST_ERROR_ACKNOWLEDGED_T; fsa[pos].start_event_handle = 0L; fsa[pos].end_event_handle = 0L; flag_changed = YES; } #ifdef LOCK_DEBUG unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS), __FILE__, __LINE__); #else unlock_region(fsa_fd, (AFD_WORD_OFFSET + (pos * sizeof(struct filetransfer_status)) + LOCK_HS)); #endif if (flag_changed == NO) { flags_unchangeable++; } else { flags_changed++; } event_action = EA_UNSET_ACK_OFFL; } } else { not_enough_errors++; } if (event_action != 0) { if (reason_str == NULL) { if (flag_changed == YES) { event_log(0L, EC_HOST, ET_MAN, event_action, "%s%c%s", host_alias[i], SEPARATOR_CHAR, user); } } else { if ((flag_changed == YES) || (event_action != EA_UNSET_ACK_OFFL)) { event_log(0L, EC_HOST, ET_MAN, event_action, "%s%c%s%c%s", host_alias[i], SEPARATOR_CHAR, user, SEPARATOR_CHAR, reason_str); } } } } } else { pos = get_dir_position(fra, dir_alias[i], no_of_dirs); if (pos == INCORRECT) { (void)fprintf(stderr, "Failed to locate `%s' in FRA.", dir_alias[i]); } else { int flag_changed = NO; if ((fra[pos].error_counter > 0) || ((start_time_val != -1) && (start_time_val != end_time_val)) || (acknowledge_type == UNSET_SELECT)) { if (acknowledge_type == ACKNOWLEDGE_SELECT) { if ((fra[pos].dir_flag & DIR_ERROR_ACKN) == 0) { fra[pos].dir_flag |= DIR_ERROR_ACKN; flag_changed = YES; flags_changed++; } else { flags_unchangeable++; } event_action = EA_ACKNOWLEDGE; } else if (acknowledge_type == OFFLINE_SELECT) { if ((fra[pos].dir_flag & DIR_ERROR_OFFLINE) == 0) { fra[pos].dir_flag |= DIR_ERROR_OFFLINE; flag_changed = YES; flags_changed++; } else { flags_unchangeable++; } event_action = EA_OFFLINE; } else /* Unset all the flags. */ { if (fra[pos].dir_flag & DIR_ERROR_ACKN) { fra[pos].dir_flag &= ~DIR_ERROR_ACKN; flag_changed = YES; } if (fra[pos].dir_flag & DIR_ERROR_OFFLINE) { fra[pos].dir_flag &= ~DIR_ERROR_OFFLINE; flag_changed = YES; } if (fra[pos].dir_flag & DIR_ERROR_ACKN_T) { fra[pos].dir_flag &= ~DIR_ERROR_ACKN_T; flag_changed = YES; } if (fra[pos].dir_flag & DIR_ERROR_OFFL_T) { fra[pos].dir_flag &= ~DIR_ERROR_OFFL_T; flag_changed = YES; } if (flag_changed == NO) { flags_unchangeable++; } else { flags_changed++; } event_action = EA_UNSET_ACK_OFFL; } } else { not_enough_errors++; } if (event_action != 0) { if (reason_str == NULL) { if (flag_changed == YES) { event_log(0L, EC_DIR, ET_MAN, event_action, "%s%c%s", dir_alias[i], SEPARATOR_CHAR, user); } } else { if ((flag_changed == YES) || (event_action != EA_UNSET_ACK_OFFL)) { event_log(0L, EC_DIR, ET_MAN, event_action, "%s%c%s%c%s", dir_alias[i], SEPARATOR_CHAR, user, SEPARATOR_CHAR, reason_str); } } } } } } /* for (i = 0; i < no_of_alias; i++) */ if (flags_changed > 0) { if (acknowledge_type == UNSET_SELECT) { if (flags_unchangeable > 0) { (void)snprintf(buffer, 256, "Unset acknowledge/offline for %d instances, %d already unset.", flags_changed, flags_unchangeable); } else { (void)snprintf(buffer, 256, "Unset acknowledge/offline for %d instances.", flags_changed); } } else { if (flags_unchangeable > 0) { if (not_enough_errors > 0) { (void)snprintf(buffer, 256, "Set acknowledge/offline for %d instances, %d already set. For %d there are not enough errors.", flags_changed, flags_unchangeable, not_enough_errors); } else { (void)snprintf(buffer, 256, "Set acknowledge/offline for %d instances, %d already set.", flags_changed, flags_unchangeable); } } else { if (not_enough_errors > 0) { (void)snprintf(buffer, 256, "Set acknowledge/offline for %d instances. For %d there are not enough errors.", flags_changed, not_enough_errors); } else { (void)snprintf(buffer, 256, "Set acknowledge/offline for %d instances.", flags_changed); } } } show_message(statusbox_w, buffer); } else if (flags_unchangeable > 0) { if (acknowledge_type == UNSET_SELECT) { (void)snprintf(buffer, 256, "Acknowledge/offline for %d instances already unset.", flags_unchangeable); show_message(statusbox_w, buffer); } else { if (not_enough_errors > 0) { (void)snprintf(buffer, 256, "Acknowledge/offline for %d instances already set. For %d there are not enough errors.", flags_unchangeable, not_enough_errors); show_message(statusbox_w, buffer); } else { if (reason_str == NULL) { (void)snprintf(buffer, 256, "Acknowledge/offline for %d instances already set.", flags_unchangeable); show_message(statusbox_w, buffer); } } } } else if (not_enough_errors > 0) { (void)snprintf(buffer, 256, "Not enough errors for %d instances.", not_enough_errors); show_message(statusbox_w, buffer); } else if ((reason_str == NULL) || (acknowledge_type == UNSET_SELECT)) { show_message(statusbox_w, "No changes."); } free(reason_str); return; } /*########################### radio_button() ############################*/ void radio_button(Widget w, XtPointer client_data, XtPointer call_data) { #if SIZEOF_LONG == 4 acknowledge_type = (int)client_data; #else union intlong { int ival[2]; long lval; } il; int byte_order = 1; il.lval = (long)client_data; if (*(char *)&byte_order == 1) { acknowledge_type = il.ival[0]; } else { acknowledge_type = il.ival[1]; } #endif return; }