/* * store_file_mask.c - Part of AFD, an automatic file distribution * program. * Copyright (c) 2000 - 2021 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 ** store_file_mask - stores all file mask to a file ** ** SYNOPSIS ** void store_file_mask(char *dir_alias, struct dir_group *dir) ** ** DESCRIPTION ** The function store_file_mask stores all file mask for the ** directory 'dir_alias' into the file: ** $AFD_WORK_DIR/files/incoming/file_mask/ ** For each file group it stores all file mask in a block ** where each file mask is separated by a binary zero. ** ** RETURN VALUES ** None. ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 14.08.2000 H.Kiehl Created ** 28.12.2003 H.Kiehl Made number of file mask unlimited. ** 10.09.2021 H.Kiehl When creating the file create it with ** a leading dot. After we finished writing ** rename without the dot. Turns out that ** creating + setting a lock was not atomic ** enough and some gf_xxx process where ** quicker in setting the lock on an empty ** file. ** */ DESCR__E_M3 #include /* sprintf(), rename() */ #include /* strerror(), memcpy() */ #include /* malloc(), free() */ #include #ifdef HAVE_FCNTL_H # include #endif #include #include "amgdefs.h" /* External global variables. */ extern int alfbl, /* Additional locked file buffer length */ alfc; /* Additional locked file counter */ extern char *alfiles, /* Additional locked files */ *p_work_dir; /*########################## store_file_mask() ##########################*/ void store_file_mask(char *dir_alias, struct dir_group *dir) { int align_offset, fbl, fc, fd, i, mod; size_t length; char *buffer, file_mask_file[MAX_PATH_LENGTH], tmp_file_mask_file[MAX_PATH_LENGTH]; if ((i = snprintf(file_mask_file, (MAX_PATH_LENGTH - MAX_DIR_ALIAS_LENGTH - 1), "%s%s%s%s/", p_work_dir, AFD_FILE_DIR, INCOMING_DIR, FILE_MASK_DIR)) >= (MAX_PATH_LENGTH - MAX_DIR_ALIAS_LENGTH - 1)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Storage for file_mask_file not large (%d bytes) enough!", (MAX_PATH_LENGTH - MAX_DIR_ALIAS_LENGTH - 1)); return; } (void)memcpy(tmp_file_mask_file, file_mask_file, i); tmp_file_mask_file[i] = '.'; if (my_strlcpy(&file_mask_file[i], dir_alias, (MAX_PATH_LENGTH - i)) >= (MAX_PATH_LENGTH - i)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Storage for file_mask_file not large (%d bytes) enough!", (MAX_PATH_LENGTH - i)); return; } if (my_strlcpy(&tmp_file_mask_file[i + 1], dir_alias, (MAX_PATH_LENGTH - i - 1)) >= (MAX_PATH_LENGTH - i - 1)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Storage for tmp_file_mask_file not large (%d bytes) enough!", (MAX_PATH_LENGTH - i - 1)); return; } if ((fd = coe_open(tmp_file_mask_file, (O_RDWR | O_CREAT | O_TRUNC), #ifdef GROUP_CAN_WRITE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP))) == -1) #else (S_IRUSR | S_IWUSR))) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to coe_open() `%s' : %s", tmp_file_mask_file, strerror(errno)); return; } if (write(fd, &dir->fgc, sizeof(int)) != sizeof(int)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to write() %d bytes to `%s' : %s", sizeof(int), tmp_file_mask_file, strerror(errno)); (void)close(fd); return; } for (i = 0; i < dir->fgc; i++) { length = sizeof(int) + sizeof(int) + alfbl + dir->file[i].fbl; mod = length % 4; if (mod != 0) { align_offset = sizeof(int) - mod; length += align_offset; } else { align_offset = 0; } fbl = alfbl + dir->file[i].fbl + align_offset; if ((buffer = malloc(length)) == NULL) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to malloc() %d bytes : %s", length, strerror(errno)); break; } fc = alfc + dir->file[i].fc; (void)memcpy(buffer, &fc, sizeof(int)); (void)memcpy(buffer + sizeof(int), &fbl, sizeof(int)); (void)memcpy(buffer + sizeof(int) + sizeof(int), alfiles, alfbl); (void)memcpy(buffer + sizeof(int) + sizeof(int) + alfbl, dir->file[i].files, dir->file[i].fbl); if (write(fd, buffer, length) != length) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to write() %d bytes to `%s' : %s", length, tmp_file_mask_file, strerror(errno)); free(buffer); break; } free(buffer); } if (close(fd) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to close() `%s' : %s", tmp_file_mask_file, strerror(errno)); } if (rename(tmp_file_mask_file, file_mask_file) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to rename() `%s' to `%s' : %s", tmp_file_mask_file, file_mask_file, strerror(errno)); } return; }