/* * handle_alias_name.c - Part of AFD, an automatic file distribution program. * Copyright (c) 2009 - 2022 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 ** handle_alias_name - set of functions to handle alias names ** ** SYNOPSIS ** void get_alias_names(void) ** ** DESCRIPTION ** The function get_alias_names() reads the alias name file and stores ** the contents in the global array alias_names. The contents of the ** alias name file looks as follows: ** ** RZ_ Ha_ ** type weather ** ** Where RZ_ is the alias name and Ha_ is the name with which we want ** to replace the alias name. ** ** The caller is responsible for freeing the memory for alias_names. ** ** RETURN VALUES ** None. It will exit with INCORRECT if it fails to allocate memory ** or fails to open the alias names file. ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 25.10.2009 H.Kiehl Created ** */ DESCR__E_M3 #include #include /* strcpy(), strerror() */ #include /* malloc(), free() */ #include #ifdef HAVE_STATX # include /* Definition of AT_* constants */ #endif #include #include /* #define _DEBUG_ALIAS_NAMES */ /* External global variables. */ extern char *p_work_dir; /* Local definitions. */ struct alias_names { char alias_from[MAX_ALIAS_NAME_LENGTH + 1]; char alias_to[MAX_ALIAS_NAME_LENGTH + 1]; }; /* Local variables. */ static int no_of_alias_names; static struct alias_names *an; /*########################## get_alias_names() ##########################*/ void get_alias_names(void) { static time_t last_read = 0; static int first_time = YES; char alias_file[MAX_PATH_LENGTH]; #ifdef HAVE_STATX struct statx stat_buf; #else struct stat stat_buf; #endif (void)snprintf(alias_file, MAX_PATH_LENGTH, "%s%s/%s", p_work_dir, ETC_DIR, ALIAS_NAME_FILE); #ifdef HAVE_STATX if (statx(0, alias_file, AT_STATX_SYNC_AS_STAT, STATX_MTIME, &stat_buf) == -1) #else if (stat(alias_file, &stat_buf) == -1) #endif { if (errno == ENOENT) { /* * Only tell user once that the rules file is missing. Otherwise * it is anoying to constantly receive this message. */ if (first_time == YES) { system_log(INFO_SIGN, __FILE__, __LINE__, _("There is no alias name file `%s'"), alias_file); first_time = NO; } } else { system_log(WARN_SIGN, __FILE__, __LINE__, #ifdef HAVE_STATX _("Failed to statx() `%s' : %s"), #else _("Failed to stat() `%s' : %s"), #endif alias_file, strerror(errno)); } } else { #ifdef HAVE_STATX if (stat_buf.stx_mtime.tv_sec != last_read) #else if (stat_buf.st_mtime != last_read) #endif { off_t file_size; char *last_ptr, *ptr, *buffer; if (first_time == YES) { first_time = NO; } if (last_read != 0) { /* * Since we are rereading the whole rules file again * lets release the memory we stored for the previous * array of alias_names. */ free(an); an = NULL; no_of_alias_names = 0; } #ifdef HAVE_STATX last_read = stat_buf.stx_mtime.tv_sec; #else last_read = stat_buf.st_mtime; #endif if (((file_size = read_file_no_cr(alias_file, &buffer, YES, __FILE__, __LINE__)) != INCORRECT) && (file_size > 0)) { int data; /* * Now that we have the contents in the buffer lets first see * how many alias names there are in the buffer so we can allocate * memory for the alias_names array. */ ptr = buffer; last_ptr = 1 + buffer + file_size; data = NO; do { if (*ptr == '#') { ptr++; while ((*ptr != '\n') && (ptr < last_ptr)) { ptr++; } } else if (*ptr == ' ') { ptr++; while (*ptr == ' ') { ptr++; } } else if (*ptr == '\t') { ptr++; while (*ptr == '\t') { ptr++; } } else if (*ptr == '\n') { if (data == YES) { no_of_alias_names++; data = NO; } ptr++; } else { data = YES; ptr++; } } while (ptr < last_ptr); if (no_of_alias_names > 0) { int count = 0, i; char *to_ptr; if ((an = malloc((no_of_alias_names * sizeof(struct alias_names)))) == NULL) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to malloc() %d bytes of memory : %s", (no_of_alias_names * sizeof(struct alias_names)), strerror(errno)); no_of_alias_names = 0; return; } for (i = 0; i < no_of_alias_names; i++) { an[i].alias_from[0] = an[i].alias_to[0] = '\0'; } i = 0; ptr = buffer; to_ptr = &an[0].alias_from[0]; do { if (*ptr == '#') { ptr++; while ((*ptr != '\n') && (ptr < last_ptr)) { ptr++; } } else if (*ptr == ' ') { ptr++; while (*ptr == ' ') { ptr++; } if (i > 0) { if (an[count].alias_to[0] == '\0') { an[count].alias_from[i] = '\0'; to_ptr = &an[count].alias_to[0]; } else { an[count].alias_to[i] = '\0'; if ((count + 1) >= no_of_alias_names) { break; } else { to_ptr = &an[count + 1].alias_from[0]; } while ((*ptr != '\n') && (ptr < last_ptr)) { ptr++; } if (*ptr == '\n') { ptr++; } count++; } i = 0; } } else if (*ptr == '\t') { ptr++; while (*ptr == '\t') { ptr++; } if (i > 0) { if (an[count].alias_to[0] == '\0') { an[count].alias_from[i] = '\0'; to_ptr = &an[count].alias_to[0]; } else { an[count].alias_to[i] = '\0'; if ((count + 1) >= no_of_alias_names) { break; } else { to_ptr = &an[count + 1].alias_from[0]; } while ((*ptr != '\n') && (ptr < last_ptr)) { ptr++; } if (*ptr == '\n') { ptr++; } count++; } i = 0; } } else if (*ptr == '\n') { if (i > 0) { an[count].alias_to[i] = '\0'; if ((count + 1) >= no_of_alias_names) { break; } else { to_ptr = &an[count + 1].alias_from[0]; } count++; } ptr++; } else { if (i < MAX_ALIAS_NAME_LENGTH) { *to_ptr = *ptr; to_ptr++; i++; } ptr++; } } while (ptr < last_ptr); } /* if (no_of_alias_names > 0) */ /* The buffer holding the contents of the rule file */ /* is no longer needed. */ free(buffer); #ifdef _DEBUG_ALIAS_NAMES { register int i; for (i = 0; i < no_of_alias_names; i++) { system_log(DEBUG_SIGN, NULL, 0, "'%s' '%s'", an[i].alias_from, an[i].alias_to); } } #endif } } /* if (stat_buf.st_mtime != last_read) */ } return; } /*###################### search_insert_alias_name() #####################*/ int search_insert_alias_name(char *search_str, char *result_str, int max_length) { int i; for (i = 0; i < no_of_alias_names; i++) { if (my_strcmp(search_str, an[i].alias_from) == 0) { int j = 0; for (j = 0; j < max_length; j++) { if (an[i].alias_to[j] == '\0') { return(j); } result_str[j] = an[i].alias_to[j]; } return(j); } } return(0); }