/*####################### check_old_time_jobs() #########################*/ void check_old_time_jobs(int no_of_jobs, char *time_dir) { DIR *dp; #ifdef _MAINTAINER_LOG maintainer_log(DEBUG_SIGN, NULL, 0, _("%s starting time dir check in %s . . ."), DIR_CHECK, time_dir); #endif /* * Search time pool directory and see if there are any old jobs * from the last DIR_CONFIG that still have to be processed. */ if ((dp = opendir(time_dir)) == NULL) { system_log((errno == ENOENT) ? DEBUG_SIGN : WARN_SIGN, __FILE__, __LINE__, _("Failed to opendir() `%s' : %s"), time_dir, strerror(errno)); } else { int i; char *ptr, str_number[MAX_INT_LENGTH], *time_dir_ptr; struct dirent *p_dir; time_dir_ptr = time_dir + strlen(time_dir); errno = 0; while ((p_dir = readdir(dp)) != NULL) { if (p_dir->d_name[0] == '.') { continue; } ptr = p_dir->d_name; i = 0; while ((*ptr != '\0') && (i < MAX_INT_LENGTH)) { if (isxdigit((int)(*ptr)) == 0) { break; } str_number[i] = *ptr; i++; ptr++; } if (*ptr == '\0') { struct stat stat_buf; (void)strcpy(time_dir_ptr, p_dir->d_name); if (stat(time_dir, &stat_buf) == -1) { if (errno != ENOENT) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to stat() `%s' : %s"), strerror(errno)); } } else { if (S_ISDIR(stat_buf.st_mode)) { int gotcha = NO; unsigned int job_id; str_number[i] = '\0'; job_id = (unsigned int)strtoul(str_number, NULL, 16); for (i = 0; i < no_of_time_jobs; i++) { if (db[time_job_list[i]].job_id == job_id) { gotcha = YES; break; } } if (gotcha == NO) { /* * Befor we try to determine the new JID number lets * try to delete the directory. If we are successful * then there where no files and we can save us a * complex search for the new one. */ if ((rmdir(time_dir) == -1) && ((errno == ENOTEMPTY) || (errno == EEXIST))) { int jid_pos = -1; /* Locate the lost job in structure job_id_data. */ for (i = 0; i < *no_of_job_ids; i++) { if (jd[i].job_id == job_id) { jid_pos = i; break; } } if (jid_pos == -1) { /* * The job cannot be found in the JID structure!? * The only thing we can do now is remove them. */ #ifdef _DELETE_LOG remove_time_dir("-", time_dir, YES, -1, -1, JID_LOOKUP_FAILURE_DEL, __FILE__, __LINE__); #else remove_time_dir("-", time_dir, YES, -1); #endif } else { unsigned int new_job_id; int new_job_gotcha = NO; /* * Hmmm. Now comes the difficult part! Try find * a current job in the JID structure that resembles * the lost job. Question is how close should the * new job resemble the old one? If we resemble it * to close we loose more data, since we do not find * a job matching. On the other hand the less we * care how well the job resembles, the higher will * be the chance that we catch the wrong job in the * JID structure. The big problem here are the * options. Well, some options we do not need to * worry about: priority, time and lock. If these * options cause difficulties, then the DIR_CONFIG * configuration is broke! */ for (i = 0; i < no_of_jobs; i++) { if ((db[i].job_id != job_id) && (dnb[jd[jid_pos].dir_id_pos].dir_id == db[i].dir_id) && (jd[jid_pos].file_mask_id == db[i].file_mask_id) && (CHECK_STRCMP(jd[jid_pos].recipient, db[i].recipient) == 0)) { #ifdef _STRONG_OPTION_CHECK if (jd[jid_pos].no_of_loptions == db[i].no_of_loptions) { char *p_loptions_db = db[i].loptions, *p_loptions_jd = jd[jid_pos].loptions; for (j = 0; j < jd[jid_pos].no_of_loptions; j++) { if ((CHECK_STRCMP(p_loptions_jd, p_loptions_db) != 0) && (strncmp(p_loptions_jd, TIME_ID, TIME_ID_LENGTH) != 0)) { gotcha = YES; break; } NEXT(p_loptions_db); NEXT(p_loptions_jd); } if (gotcha == NO) { if (jd[jid_pos].no_of_soptions == db[i].no_of_soptions) { if (jd[jid_pos].no_of_soptions > 0) { if (CHECK_STRCMP(jd[jid_pos].soptions, db[i].soptions) != 0) { gotcha = YES; } } if (gotcha == NO) { new_job_id = db[i].job_id; new_job_gotcha = YES; break; } } } } #else new_job_id = db[i].job_id; new_job_gotcha = YES; break; #endif } } /* for (i = 0; i < no_of_jobs; i++) */ if (new_job_gotcha == NO) { /* * Since we were not able to locate a similar * job lets assume it has been taken from the * DIR_CONFIG. In that case we have to remove * all files. */ #ifdef _DELETE_LOG remove_time_dir(jd[jid_pos].host_alias, time_dir, YES, jd[jid_pos].job_id, jd[jid_pos].dir_id, JID_LOOKUP_FAILURE_DEL, __FILE__, __LINE__); #else remove_time_dir(jd[jid_pos].host_alias, time_dir, YES, jd[jid_pos].job_id); #endif } else { /* * Lets move all files from the old job directory * to the new one. */ move_time_dir(time_dir, new_job_id); } } } /* if ((rmdir(time_dir) == -1) && (errno == ENOTEMPTY)) */ } /* if (gotcha == NO) */ } /* if (S_ISDIR(stat_buf.st_mode) == 0) */ } /* stat() successful */ } /* if (*ptr == '\0') */ errno = 0; } /* while ((p_dir = readdir(dp)) != NULL) */ *time_dir_ptr = '\0'; if (errno) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to readdir() `%s' : %s"), time_dir, strerror(errno)); } if (closedir(dp) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to closedir() `%s' : %s"), time_dir, strerror(errno)); } } #ifdef _MAINTAINER_LOG maintainer_log(DEBUG_SIGN, NULL, 0, _("%s time dir check done."), DIR_CHECK); #endif return; }
/*+++++++++++++++++++++++++++++ check_list() ++++++++++++++++++++++++++++*/ static int check_list(char *file, off_t file_size, time_t file_mtime, int *files_to_retrieve, off_t *file_size_to_retrieve, int *more_files_in_list) { int i; if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES)) { for (i = 0; i < no_of_listed_files; i++) { if (CHECK_STRCMP(rl[i].file_name, file) == 0) { rl[i].in_list = YES; if (((rl[i].assigned == 0) || (rl[i].retrieved == YES)) && (((db.special_flag & OLD_ERROR_JOB) == 0) || #ifdef LOCK_DEBUG (lock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i), __FILE__, __LINE__) == LOCK_IS_NOT_SET) #else (lock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i)) == LOCK_IS_NOT_SET) #endif )) { int ret; rl[i].file_mtime = file_mtime; rl[i].got_date = YES; rl[i].size = file_size; rl[i].prev_size = 0; if ((fra[db.fra_pos].ignore_size == -1) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_EQUAL) && (fra[db.fra_pos].ignore_size == rl[i].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_LESS_THEN) && (fra[db.fra_pos].ignore_size < rl[i].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_GREATER_THEN) && (fra[db.fra_pos].ignore_size > rl[i].size))) { if (fra[db.fra_pos].ignore_file_time == 0) { *file_size_to_retrieve += rl[i].size; *files_to_retrieve += 1; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES) || ((*files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size))) #else if ((*files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size)) #endif { rl[i].retrieved = NO; rl[i].assigned = (unsigned char)db.job_no + 1; } else { rl[i].assigned = 0; *file_size_to_retrieve -= rl[i].size; *files_to_retrieve -= 1; *more_files_in_list = YES; } ret = 0; } else { time_t diff_time; diff_time = current_time - rl[i].file_mtime; if (((fra[db.fra_pos].gt_lt_sign & IFTIME_EQUAL) && (fra[db.fra_pos].ignore_file_time == diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_LESS_THEN) && (fra[db.fra_pos].ignore_file_time < diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_GREATER_THEN) && (fra[db.fra_pos].ignore_file_time > diff_time))) { *file_size_to_retrieve += rl[i].size; *files_to_retrieve += 1; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES) || ((*files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size))) #else if ((*files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size)) #endif { rl[i].retrieved = NO; rl[i].assigned = (unsigned char)db.job_no + 1; } else { rl[i].assigned = 0; *file_size_to_retrieve -= rl[i].size; *files_to_retrieve -= 1; *more_files_in_list = YES; } ret = 0; } else { ret = 1; } } #ifdef DEBUG_ASSIGNMENT trans_log(DEBUG_SIGN, __FILE__, __LINE__, NULL, NULL, # if SIZEOF_OFF_T == 4 "%s assigned %d: file_name=%s assigned=%d size=%ld", # else "%s assigned %d: file_name=%s assigned=%d size=%lld", # endif (fra[db.fra_pos].ls_data_alias[0] == '\0') ? fra[db.fra_pos].dir_alias : fra[db.fra_pos].ls_data_alias, i, rl[i].file_name, (int)rl[i].assigned, (pri_off_t)rl[i].size); #endif /* DEBUG_ASSIGNMENT */ } else { ret = 1; } if (db.special_flag & OLD_ERROR_JOB) { #ifdef LOCK_DEBUG unlock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i), __FILE__, __LINE__); #else unlock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i)); #endif } return(ret); } else { return(1); } } } /* for (i = 0; i < no_of_listed_files; i++) */ } else { /* Check if this file is in the list. */ for (i = 0; i < no_of_listed_files; i++) { if (CHECK_STRCMP(rl[i].file_name, file) == 0) { rl[i].in_list = YES; if ((rl[i].assigned != 0) || ((fra[db.fra_pos].stupid_mode == GET_ONCE_ONLY) && (rl[i].retrieved == YES))) { return(1); } if (((db.special_flag & OLD_ERROR_JOB) == 0) || #ifdef LOCK_DEBUG (lock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i), __FILE__, __LINE__) == LOCK_IS_NOT_SET) #else (lock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i)) == LOCK_IS_NOT_SET) #endif ) { int ret; off_t prev_size = 0; if (rl[i].file_mtime != file_mtime) { rl[i].file_mtime = file_mtime; rl[i].retrieved = NO; rl[i].assigned = 0; } rl[i].got_date = YES; if (rl[i].size != file_size) { prev_size = rl[i].size; rl[i].size = file_size; rl[i].retrieved = NO; rl[i].assigned = 0; } if (rl[i].retrieved == NO) { if ((fra[db.fra_pos].ignore_size == -1) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_EQUAL) && (fra[db.fra_pos].ignore_size == rl[i].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_LESS_THEN) && (fra[db.fra_pos].ignore_size < rl[i].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_GREATER_THEN) && (fra[db.fra_pos].ignore_size > rl[i].size))) { off_t size_to_retrieve; if ((rl[i].got_date == NO) || (fra[db.fra_pos].ignore_file_time == 0)) { if ((fra[db.fra_pos].stupid_mode == APPEND_ONLY) && (rl[i].size > prev_size)) { size_to_retrieve = rl[i].size - prev_size; } else { size_to_retrieve = rl[i].size; } rl[i].prev_size = prev_size; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES) || (((*files_to_retrieve + 1) < fra[db.fra_pos].max_copied_files) && ((*file_size_to_retrieve + size_to_retrieve) < fra[db.fra_pos].max_copied_file_size))) #else if (((*files_to_retrieve + 1) < fra[db.fra_pos].max_copied_files) && ((*file_size_to_retrieve + size_to_retrieve) < fra[db.fra_pos].max_copied_file_size)) #endif { rl[i].assigned = (unsigned char)db.job_no + 1; *file_size_to_retrieve += size_to_retrieve; *files_to_retrieve += 1; } else { rl[i].assigned = 0; *more_files_in_list = YES; } ret = 0; } else { time_t diff_time; diff_time = current_time - rl[i].file_mtime; if (((fra[db.fra_pos].gt_lt_sign & IFTIME_EQUAL) && (fra[db.fra_pos].ignore_file_time == diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_LESS_THEN) && (fra[db.fra_pos].ignore_file_time < diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_GREATER_THEN) && (fra[db.fra_pos].ignore_file_time > diff_time))) { if ((fra[db.fra_pos].stupid_mode == APPEND_ONLY) && (rl[i].size > prev_size)) { size_to_retrieve = rl[i].size - prev_size; } else { size_to_retrieve = rl[i].size; } rl[i].prev_size = prev_size; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES) || (((*files_to_retrieve + 1) < fra[db.fra_pos].max_copied_files) && ((*file_size_to_retrieve + size_to_retrieve) < fra[db.fra_pos].max_copied_file_size))) #else if (((*files_to_retrieve + 1) < fra[db.fra_pos].max_copied_files) && ((*file_size_to_retrieve + size_to_retrieve) < fra[db.fra_pos].max_copied_file_size)) #endif { rl[i].assigned = (unsigned char)db.job_no + 1; *file_size_to_retrieve += size_to_retrieve; *files_to_retrieve += 1; } else { rl[i].assigned = 0; *more_files_in_list = YES; } ret = 0; } else { ret = 1; } } #ifdef DEBUG_ASSIGNMENT trans_log(DEBUG_SIGN, __FILE__, __LINE__, NULL, NULL, # if SIZEOF_OFF_T == 4 "%s assigned %d: file_name=%s assigned=%d size=%ld", # else "%s assigned %d: file_name=%s assigned=%d size=%lld", # endif (fra[db.fra_pos].ls_data_alias[0] == '\0') ? fra[db.fra_pos].dir_alias : fra[db.fra_pos].ls_data_alias, i, rl[i].file_name, (int)rl[i].assigned, (pri_off_t)rl[i].size); #endif /* DEBUG_ASSIGNMENT */ } else { ret = 1; } } else { ret = 1; } if (db.special_flag & OLD_ERROR_JOB) { #ifdef LOCK_DEBUG unlock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i), __FILE__, __LINE__); #else unlock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i)); #endif } return(ret); } else { return(1); } } } /* for (i = 0; i < no_of_listed_files; i++) */ } /* Add this file to the list. */ if ((no_of_listed_files != 0) && ((no_of_listed_files % RETRIEVE_LIST_STEP_SIZE) == 0)) { char *ptr; size_t new_size = (((no_of_listed_files / RETRIEVE_LIST_STEP_SIZE) + 1) * RETRIEVE_LIST_STEP_SIZE * sizeof(struct retrieve_list)) + AFD_WORD_OFFSET; ptr = (char *)rl - AFD_WORD_OFFSET; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES)) { if ((ptr = realloc(ptr, new_size)) == NULL) { system_log(ERROR_SIGN, __FILE__, __LINE__, "realloc() error : %s", strerror(errno)); (void)ftp_quit(); exit(INCORRECT); } } else { #endif if ((ptr = mmap_resize(rl_fd, ptr, new_size)) == (caddr_t) -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "mmap_resize() error : %s", strerror(errno)); (void)ftp_quit(); exit(INCORRECT); } rl_size = new_size; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH } #endif if (no_of_listed_files < 0) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmmm, no_of_listed_files = %d", no_of_listed_files); no_of_listed_files = 0; } *(int *)ptr = no_of_listed_files; ptr += AFD_WORD_OFFSET; rl = (struct retrieve_list *)ptr; } (void)strcpy(rl[no_of_listed_files].file_name, file); rl[no_of_listed_files].retrieved = NO; rl[no_of_listed_files].in_list = YES; rl[no_of_listed_files].size = file_size; rl[no_of_listed_files].prev_size = 0; rl[no_of_listed_files].file_mtime = file_mtime; rl[no_of_listed_files].got_date = YES; if ((fra[db.fra_pos].ignore_size == -1) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_EQUAL) && (fra[db.fra_pos].ignore_size == rl[no_of_listed_files].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_LESS_THEN) && (fra[db.fra_pos].ignore_size < rl[no_of_listed_files].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_GREATER_THEN) && (fra[db.fra_pos].ignore_size > rl[no_of_listed_files].size))) { if ((rl[no_of_listed_files].got_date == NO) || (fra[db.fra_pos].ignore_file_time == 0)) { *file_size_to_retrieve += file_size; *files_to_retrieve += 1; no_of_listed_files++; } else { time_t diff_time; diff_time = current_time - rl[no_of_listed_files].file_mtime; if (((fra[db.fra_pos].gt_lt_sign & IFTIME_EQUAL) && (fra[db.fra_pos].ignore_file_time == diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_LESS_THEN) && (fra[db.fra_pos].ignore_file_time < diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_GREATER_THEN) && (fra[db.fra_pos].ignore_file_time > diff_time))) { *file_size_to_retrieve += file_size; *files_to_retrieve += 1; no_of_listed_files++; } else { return(1); } } #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES) || ((*files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size))) #else if ((*files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size)) #endif { rl[no_of_listed_files - 1].assigned = (unsigned char)db.job_no + 1; } else { rl[no_of_listed_files - 1].assigned = 0; *file_size_to_retrieve -= file_size; *files_to_retrieve -= 1; *more_files_in_list = YES; } *(int *)((char *)rl - AFD_WORD_OFFSET) = no_of_listed_files; #ifdef DEBUG_ASSIGNMENT trans_log(DEBUG_SIGN, __FILE__, __LINE__, NULL, NULL, # if SIZEOF_OFF_T == 4 "%s assigned %d: file_name=%s assigned=%d size=%ld", # else "%s assigned %d: file_name=%s assigned=%d size=%lld", # endif (fra[db.fra_pos].ls_data_alias[0] == '\0') ? fra[db.fra_pos].dir_alias : fra[db.fra_pos].ls_data_alias, i, rl[i].file_name, (int)rl[i].assigned, (pri_off_t)rl[i].size); #endif /* DEBUG_ASSIGNMENT */ return(0); } else { return(1); } }
/*############################ create_fsa() #############################*/ void create_fsa(void) { int fsa_id_fd, i, k, loops, old_fsa_fd = -1, old_fsa_id, old_no_of_hosts = -1, pagesize, rest, size; off_t old_fsa_size = -1; char buffer[4096], fsa_id_file[MAX_PATH_LENGTH], new_fsa_stat[MAX_PATH_LENGTH], old_fsa_stat[MAX_PATH_LENGTH], *ptr = NULL; struct filetransfer_status *old_fsa = NULL; struct flock wlock = {F_WRLCK, SEEK_SET, 0, 1}; struct stat stat_buf; fsa_size = -1; /* Initialise all pathnames and file descriptors. */ (void)strcpy(fsa_id_file, p_work_dir); (void)strcat(fsa_id_file, FIFO_DIR); (void)strcpy(old_fsa_stat, fsa_id_file); (void)strcat(old_fsa_stat, FSA_STAT_FILE); (void)strcat(fsa_id_file, FSA_ID_FILE); /* * First just try open the fsa_id_file. If this fails create * the file and initialise old_fsa_id with -1. */ if ((fsa_id_fd = open(fsa_id_file, O_RDWR)) > -1) { /* * Lock FSA ID file. If it is already locked * (by edit_hc dialog) wait for it to clear the lock * again. */ if (fcntl(fsa_id_fd, F_SETLKW, &wlock) < 0) { /* Is lock already set or are we setting it again? */ if ((errno != EACCES) && (errno != EAGAIN) && (errno != EBUSY)) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not set write lock for %s : %s", fsa_id_file, strerror(errno)); exit(INCORRECT); } } /* Read the FSA file ID. */ if (read(fsa_id_fd, &old_fsa_id, sizeof(int)) < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not read the value of the FSA file ID : %s", strerror(errno)); exit(INCORRECT); } } else { if ((fsa_id_fd = open(fsa_id_file, (O_RDWR | O_CREAT), FILE_MODE)) < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not open %s : %s", fsa_id_file, strerror(errno)); exit(INCORRECT); } old_fsa_id = -1; } /* * We now have to determine if this is the first time that the * AMG is being run. The only way to find this out is to see * whether the startup time of the AFD has been set. If it is * not set (i.e. 0), it is the first time. */ if (first_time == YES) { if (p_afd_status->start_time > 0) { first_time = NO; } else { first_time = YES; } } /* Set flag to indicate that we are rereading the DIR_CONFIG. */ p_afd_status->amg_jobs |= REREADING_DIR_CONFIG; /* * Mark memory mapped region as old, so no process puts * any new information into the region after we * have copied it into the new region. */ if (old_fsa_id > -1) { /* Attach to old region. */ ptr = old_fsa_stat + strlen(old_fsa_stat); (void)snprintf(ptr, MAX_PATH_LENGTH - (ptr - old_fsa_stat), ".%d", old_fsa_id); /* Get the size of the old FSA file. */ if (stat(old_fsa_stat, &stat_buf) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to stat() %s : %s", old_fsa_stat, strerror(errno)); old_fsa_id = -1; } else { if (stat_buf.st_size > 0) { if ((old_fsa_fd = open(old_fsa_stat, O_RDWR)) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to open() %s : %s", old_fsa_stat, strerror(errno)); old_fsa_id = old_fsa_fd = -1; } else { /* * Lock the whole region so all sf_xxx process stop * writting data to the old FSA. */ wlock.l_len = stat_buf.st_size; if (fcntl(old_fsa_fd, F_SETLKW, &wlock) < 0) { /* Is lock already set or are we setting it again? */ if ((errno != EACCES) && (errno != EAGAIN) && (errno != EBUSY)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Could not set write lock for %s : %s", old_fsa_stat, strerror(errno)); } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Could not set write lock for %s : %s", old_fsa_stat, strerror(errno)); } } #ifdef HAVE_MMAP if ((ptr = mmap(NULL, stat_buf.st_size, (PROT_READ | PROT_WRITE), MAP_SHARED, old_fsa_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, stat_buf.st_size, (PROT_READ | PROT_WRITE), MAP_SHARED, old_fsa_stat, 0)) == (caddr_t) -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "mmap() error : %s", strerror(errno)); old_fsa_id = -1; } else { if (*(int *)ptr == STALE) { system_log(WARN_SIGN, __FILE__, __LINE__, "FSA in %s is stale! Ignoring this FSA.", old_fsa_stat); old_fsa_id = -1; } else { old_fsa_size = stat_buf.st_size; } /* * We actually could remove the old file now. Better * do it when we are done with it. */ } /* * Do NOT close the old file! Else some file system * optimisers (like fsr in Irix 5.x) move the contents * of the memory mapped file! */ } } else { old_fsa_id = -1; } } if (old_fsa_id != -1) { old_no_of_hosts = *(int *)ptr; /* Now mark it as stale. */ *(int *)ptr = STALE; /* Check if the version has changed. */ if (*(ptr + SIZEOF_INT + 1 + 1 + 1) != CURRENT_FSA_VERSION) { unsigned char old_version = *(ptr + SIZEOF_INT + 1 + 1 + 1); /* Unmap old FSA file. */ #ifdef HAVE_MMAP if (munmap(ptr, old_fsa_size) == -1) #else if (munmap_emu(ptr) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to munmap() %s : %s", old_fsa_stat, strerror(errno)); } if ((ptr = convert_fsa(old_fsa_fd, old_fsa_stat, &old_fsa_size, old_no_of_hosts, old_version, CURRENT_FSA_VERSION)) == NULL) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to convert_fsa() %s", old_fsa_stat); old_fsa_id = -1; } } /* FSA version has changed. */ if (old_fsa_id != -1) { /* Move pointer to correct position so */ /* we can extract the relevant data. */ ptr += AFD_WORD_OFFSET; old_fsa = (struct filetransfer_status *)ptr; } } } /* * Create the new mmap region. */ /* First calculate the new size. The + 1 after no_of_hosts is in case */ /* the function get_new_positions() needs to write some data not */ /* visible to the user. */ fsa_size = AFD_WORD_OFFSET + ((no_of_hosts + 1) * sizeof(struct filetransfer_status)); if ((old_fsa_id + 1) > -1) { fsa_id = old_fsa_id + 1; } else { fsa_id = 0; } (void)snprintf(new_fsa_stat, MAX_PATH_LENGTH, "%s%s%s.%d", p_work_dir, FIFO_DIR, FSA_STAT_FILE, fsa_id); /* Now map the new FSA region to a file. */ if ((fsa_fd = open(new_fsa_stat, (O_RDWR | O_CREAT | O_TRUNC), FILE_MODE)) == -1) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Failed to open() %s : %s", new_fsa_stat, strerror(errno)); exit(INCORRECT); } /* * Write the complete file before we mmap() to it. If we just lseek() * to the end, write one byte and then mmap to it can cause a SIGBUS * on some systems when the disk is full and data is written to the * mapped area. So to detect that the disk is full always write the * complete file we want to map. */ loops = fsa_size / 4096; rest = fsa_size % 4096; (void)memset(buffer, 0, 4096); for (i = 0; i < loops; i++) { if (write(fsa_fd, buffer, 4096) != 4096) { system_log(FATAL_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); exit(INCORRECT); } } if (rest > 0) { if (write(fsa_fd, buffer, rest) != rest) { system_log(FATAL_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); exit(INCORRECT); } } #ifdef HAVE_MMAP if ((ptr = mmap(NULL, fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, fsa_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, new_fsa_stat, 0)) == (caddr_t) -1) #endif { system_log(FATAL_SIGN, __FILE__, __LINE__, "mmap() error : %s", strerror(errno)); exit(INCORRECT); } /* Write number of hosts to new memory mapped region. */ *(int*)ptr = no_of_hosts; /* Initialize HOST_CONFIG counter. */ *(unsigned char *)(ptr + SIZEOF_INT) = 0; /* Reposition fsa pointer after no_of_hosts. */ ptr += AFD_WORD_OFFSET; fsa = (struct filetransfer_status *)ptr; /* * Copy all the old and new data into the new mapped region. */ size = MAX_NO_PARALLEL_JOBS * sizeof(struct status); if (old_fsa_id < 0) { struct system_data sd; /* * There is NO old FSA. */ for (i = 0; i < no_of_hosts; i++) { (void)memcpy(fsa[i].host_alias, hl[i].host_alias, MAX_HOSTNAME_LENGTH + 1); (void)memcpy(fsa[i].real_hostname[0], hl[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(fsa[i].real_hostname[1], hl[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(fsa[i].proxy_name, hl[i].proxy_name, MAX_PROXY_NAME_LENGTH + 1); fsa[i].allowed_transfers = hl[i].allowed_transfers; fsa[i].max_errors = hl[i].max_errors; fsa[i].retry_interval = hl[i].retry_interval; fsa[i].block_size = hl[i].transfer_blksize; fsa[i].max_successful_retries = hl[i].successful_retries; fsa[i].file_size_offset = hl[i].file_size_offset; fsa[i].transfer_timeout = hl[i].transfer_timeout; fsa[i].protocol = hl[i].protocol; fsa[i].transfer_rate_limit = hl[i].transfer_rate_limit; fsa[i].trl_per_process = hl[i].transfer_rate_limit; fsa[i].mc_ct_rate_limit = hl[i].transfer_rate_limit; fsa[i].mc_ctrl_per_process = hl[i].transfer_rate_limit; fsa[i].ttl = hl[i].ttl; fsa[i].socksnd_bufsize = hl[i].socksnd_bufsize; fsa[i].sockrcv_bufsize = hl[i].sockrcv_bufsize; fsa[i].keep_connected = hl[i].keep_connected; fsa[i].warn_time = hl[i].warn_time; #ifdef WITH_DUP_CHECK fsa[i].dup_check_flag = hl[i].dup_check_flag; fsa[i].dup_check_timeout = hl[i].dup_check_timeout; #endif fsa[i].host_id = get_str_checksum(fsa[i].host_alias); fsa[i].protocol_options = hl[i].protocol_options; fsa[i].mc_nack_counter = 0; fsa[i].special_flag = 0; if (hl[i].in_dir_config == YES) { fsa[i].special_flag |= HOST_IN_DIR_CONFIG; } if (hl[i].host_status & HOST_CONFIG_HOST_DISABLED) { fsa[i].special_flag |= HOST_DISABLED; } if (hl[i].protocol_options & KEEP_CON_NO_SEND_2) { fsa[i].special_flag |= KEEP_CON_NO_SEND; } if (hl[i].protocol_options & KEEP_CON_NO_FETCH_2) { fsa[i].special_flag |= KEEP_CON_NO_FETCH; } if (hl[i].host_status & HOST_TWO_FLAG) { fsa[i].host_toggle = HOST_TWO; } else { fsa[i].host_toggle = DEFAULT_TOGGLE_HOST; } /* Determine the host name to display. */ fsa[i].original_toggle_pos = NONE; (void)memcpy(fsa[i].host_dsp_name, fsa[i].host_alias, MAX_HOSTNAME_LENGTH + 1); fsa[i].toggle_pos = strlen(fsa[i].host_alias); if (hl[i].host_toggle_str[0] == '\0') { fsa[i].host_toggle_str[0] = '\0'; if (fsa[i].real_hostname[0][0] == '\0') { (void)memcpy(fsa[i].real_hostname[0], hl[i].fullname, MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[i].real_hostname[0], hl[i].fullname, MAX_REAL_HOSTNAME_LENGTH); } } else { (void)memcpy(fsa[i].host_toggle_str, hl[i].host_toggle_str, MAX_TOGGLE_STR_LENGTH); if (hl[i].host_toggle_str[0] == AUTO_TOGGLE_OPEN) { fsa[i].auto_toggle = ON; } else { fsa[i].auto_toggle = OFF; } fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[(int)fsa[i].host_toggle]; fsa[i].host_dsp_name[(int)(fsa[i].toggle_pos + 1)] = '\0'; if (fsa[i].real_hostname[0][0] == '\0') { (void)strcpy(fsa[i].real_hostname[0], fsa[i].host_dsp_name); (void)memcpy(hl[i].real_hostname[0], fsa[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); } if (fsa[i].real_hostname[1][0] == '\0') { (void)strcpy(fsa[i].real_hostname[1], fsa[i].host_dsp_name); if (fsa[i].host_toggle == HOST_ONE) { fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[HOST_TWO]; } else { fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[HOST_ONE]; } (void)memcpy(hl[i].real_hostname[1], fsa[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); } } (void)memset(&hl[i].fullname[0], 0, MAX_FILENAME_LENGTH); fsa[i].host_status = 0; if (hl[i].host_status & STOP_TRANSFER_STAT) { fsa[i].host_status |= STOP_TRANSFER_STAT; } if (hl[i].host_status & PAUSE_QUEUE_STAT) { fsa[i].host_status |= PAUSE_QUEUE_STAT; } if (hl[i].host_status & HOST_ERROR_OFFLINE_STATIC) { fsa[i].host_status |= HOST_ERROR_OFFLINE_STATIC; } if (hl[i].host_status & DO_NOT_DELETE_DATA) { fsa[i].host_status |= DO_NOT_DELETE_DATA; } fsa[i].error_counter = 0; fsa[i].total_errors = 0; for (k = 0; k < ERROR_HISTORY_LENGTH; k++) { fsa[i].error_history[k] = 0; } fsa[i].jobs_queued = 0; fsa[i].file_counter_done = 0; fsa[i].bytes_send = 0; fsa[i].connections = 0; fsa[i].active_transfers = 0; fsa[i].successful_retries = 0; fsa[i].debug = NO; fsa[i].last_connection = fsa[i].last_retry_time = time(NULL); fsa[i].first_error_time = 0L; fsa[i].start_event_handle = 0L; fsa[i].end_event_handle = 0L; (void)memset(&fsa[i].job_status, 0, size); for (k = 0; k < fsa[i].allowed_transfers; k++) { fsa[i].job_status[k].connect_status = DISCONNECT; fsa[i].job_status[k].proc_id = -1; #ifdef _WITH_BURST_2 fsa[i].job_status[k].job_id = NO_ID; #endif } for (k = fsa[i].allowed_transfers; k < MAX_NO_PARALLEL_JOBS; k++) { fsa[i].job_status[k].no_of_files = -1; fsa[i].job_status[k].proc_id = -1; } } /* for (i = 0; i < no_of_hosts; i++) */ /* Copy configuration information from the old FSA when this */ /* is stored in system_data file. */ if (get_system_data(&sd) == SUCCESS) { ptr = (char *)fsa - AFD_FEATURE_FLAG_OFFSET_END; *ptr = sd.fsa_feature_flag; } } else /* There is an old database file. */ { int host_pos, no_of_gotchas = 0; char *gotcha = NULL; /* * The gotcha array is used to find hosts that are in the * old FSA but not in the HOST_CONFIG file. */ if ((gotcha = malloc(old_no_of_hosts)) == NULL) { system_log(FATAL_SIGN, __FILE__, __LINE__, "malloc() error [%d bytes] : %s", old_no_of_hosts, strerror(errno)); exit(INCORRECT); } (void)memset(gotcha, NO, old_no_of_hosts); for (i = 0; i < no_of_hosts; i++) { (void)memcpy(fsa[i].host_alias, hl[i].host_alias, MAX_HOSTNAME_LENGTH + 1); (void)memcpy(fsa[i].host_dsp_name, fsa[i].host_alias, MAX_HOSTNAME_LENGTH + 1); (void)memcpy(fsa[i].real_hostname[0], hl[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(fsa[i].real_hostname[1], hl[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(fsa[i].proxy_name, hl[i].proxy_name, MAX_PROXY_NAME_LENGTH + 1); fsa[i].allowed_transfers = hl[i].allowed_transfers; fsa[i].max_errors = hl[i].max_errors; fsa[i].retry_interval = hl[i].retry_interval; fsa[i].block_size = hl[i].transfer_blksize; fsa[i].max_successful_retries = hl[i].successful_retries; fsa[i].file_size_offset = hl[i].file_size_offset; fsa[i].transfer_timeout = hl[i].transfer_timeout; fsa[i].protocol = hl[i].protocol; fsa[i].protocol_options = hl[i].protocol_options; fsa[i].transfer_rate_limit = hl[i].transfer_rate_limit; fsa[i].ttl = hl[i].ttl; fsa[i].socksnd_bufsize = hl[i].socksnd_bufsize; fsa[i].sockrcv_bufsize = hl[i].sockrcv_bufsize; fsa[i].keep_connected = hl[i].keep_connected; fsa[i].warn_time = hl[i].warn_time; #ifdef WITH_DUP_CHECK fsa[i].dup_check_flag = hl[i].dup_check_flag; fsa[i].dup_check_timeout = hl[i].dup_check_timeout; #endif if (hl[i].host_status & HOST_TWO_FLAG) { fsa[i].host_toggle = HOST_TWO; } else { fsa[i].host_toggle = DEFAULT_TOGGLE_HOST; } /* * Search in the old FSA for this host. If it is there use * the values from the old FSA or else initialise them with * defaults. When we find an old entry, remember this so we * can later check if there are entries in the old FSA but * there are no corresponding entries in the HOST_CONFIG. * This will then have to be updated in the HOST_CONFIG file. */ host_pos = INCORRECT; for (k = 0; k < old_no_of_hosts; k++) { if (gotcha[k] != YES) { if (CHECK_STRCMP(old_fsa[k].host_alias, hl[i].host_alias) == 0) { host_pos = k; break; } } } if (host_pos != INCORRECT) { no_of_gotchas++; gotcha[host_pos] = YES; /* * When restarting the AMG and we did change the switching * information we will not recognise this change. Thus we have * to always evaluate the host name :-( */ fsa[i].toggle_pos = strlen(fsa[i].host_alias); if (hl[i].host_toggle_str[0] == '\0') { fsa[i].host_toggle_str[0] = '\0'; fsa[i].original_toggle_pos = NONE; fsa[i].host_toggle = DEFAULT_TOGGLE_HOST; if (fsa[i].real_hostname[0][0] == '\0') { (void)memcpy(fsa[i].real_hostname[0], hl[i].fullname, MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[i].real_hostname[0], hl[i].fullname, MAX_REAL_HOSTNAME_LENGTH); } } else { (void)memcpy(fsa[i].host_toggle_str, hl[i].host_toggle_str, MAX_TOGGLE_STR_LENGTH); if (hl[i].host_toggle_str[0] == AUTO_TOGGLE_OPEN) { fsa[i].auto_toggle = ON; if (old_fsa[host_pos].original_toggle_pos == NONE) { fsa[i].successful_retries = 0; } else { fsa[i].successful_retries = old_fsa[host_pos].successful_retries; } } else { fsa[i].auto_toggle = OFF; fsa[i].original_toggle_pos = NONE; fsa[i].successful_retries = 0; } fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[(int)fsa[i].host_toggle]; fsa[i].host_dsp_name[(int)(fsa[i].toggle_pos + 1)] = '\0'; if (fsa[i].real_hostname[0][0] == '\0') { (void)strcpy(fsa[i].real_hostname[0], fsa[i].host_dsp_name); (void)memcpy(hl[i].real_hostname[0], fsa[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); } if (fsa[i].real_hostname[1][0] == '\0') { (void)strcpy(fsa[i].real_hostname[1], fsa[i].host_dsp_name); if (fsa[i].host_toggle == HOST_ONE) { fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[HOST_TWO]; } else { fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[HOST_ONE]; } (void)memcpy(hl[i].real_hostname[1], fsa[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); } } (void)memset(&hl[i].fullname[0], 0, MAX_FILENAME_LENGTH); if (fsa[i].real_hostname[0][0] == '\0') { (void)memcpy(fsa[i].real_hostname[0], old_fsa[host_pos].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[i].real_hostname[0], old_fsa[host_pos].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); } if (fsa[i].real_hostname[1][0] == '\0') { (void)memcpy(fsa[i].real_hostname[1], old_fsa[host_pos].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[i].real_hostname[1], old_fsa[host_pos].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); } fsa[i].host_status = old_fsa[host_pos].host_status; fsa[i].error_counter = old_fsa[host_pos].error_counter; fsa[i].total_errors = old_fsa[host_pos].total_errors; for (k = 0; k < ERROR_HISTORY_LENGTH; k++) { fsa[i].error_history[k] = old_fsa[host_pos].error_history[k]; } fsa[i].jobs_queued = old_fsa[host_pos].jobs_queued; fsa[i].file_counter_done = old_fsa[host_pos].file_counter_done; fsa[i].bytes_send = old_fsa[host_pos].bytes_send; fsa[i].connections = old_fsa[host_pos].connections; fsa[i].active_transfers = old_fsa[host_pos].active_transfers; fsa[i].last_connection = old_fsa[host_pos].last_connection; fsa[i].last_retry_time = old_fsa[host_pos].last_retry_time; fsa[i].first_error_time = old_fsa[host_pos].first_error_time; fsa[i].start_event_handle = old_fsa[host_pos].start_event_handle; fsa[i].end_event_handle = old_fsa[host_pos].end_event_handle; fsa[i].total_file_counter = old_fsa[host_pos].total_file_counter; fsa[i].total_file_size = old_fsa[host_pos].total_file_size; fsa[i].debug = old_fsa[host_pos].debug; fsa[i].special_flag = old_fsa[host_pos].special_flag; fsa[i].original_toggle_pos = old_fsa[host_pos].original_toggle_pos; if (old_fsa[host_pos].host_id == 0) { fsa[i].host_id = get_str_checksum(fsa[i].host_alias); } else { fsa[i].host_id = old_fsa[host_pos].host_id; } fsa[i].mc_ct_rate_limit = old_fsa[host_pos].mc_ct_rate_limit; fsa[i].mc_nack_counter = old_fsa[host_pos].mc_nack_counter; if (fsa[i].active_transfers > 1) { fsa[i].trl_per_process = fsa[i].transfer_rate_limit / fsa[i].active_transfers; fsa[i].mc_ctrl_per_process = fsa[i].mc_ct_rate_limit / fsa[i].active_transfers; } else { fsa[i].trl_per_process = fsa[i].transfer_rate_limit; fsa[i].mc_ctrl_per_process = fsa[i].mc_ct_rate_limit; } /* Copy all job entries. */ (void)memcpy(&fsa[i].job_status, &old_fsa[host_pos].job_status, size); } else /* This host is not in the old FSA, therefor it is new. */ { fsa[i].original_toggle_pos = NONE; fsa[i].toggle_pos = strlen(fsa[i].host_alias); if (hl[i].host_toggle_str[0] == '\0') { fsa[i].host_toggle_str[0] = '\0'; if (fsa[i].real_hostname[0][0] == '\0') { (void)memcpy(fsa[i].real_hostname[0], hl[i].fullname, MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[i].real_hostname[0], hl[i].fullname, MAX_REAL_HOSTNAME_LENGTH); } } else { (void)memcpy(fsa[i].host_toggle_str, hl[i].host_toggle_str, MAX_TOGGLE_STR_LENGTH); if (hl[i].host_toggle_str[0] == AUTO_TOGGLE_OPEN) { fsa[i].auto_toggle = ON; } else { fsa[i].auto_toggle = OFF; } fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[(int)fsa[i].host_toggle]; fsa[i].host_dsp_name[(int)(fsa[i].toggle_pos + 1)] = '\0'; if (fsa[i].real_hostname[0][0] == '\0') { (void)strcpy(fsa[i].real_hostname[0], fsa[i].host_dsp_name); (void)memcpy(hl[i].real_hostname[0], fsa[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); } if (fsa[i].real_hostname[1][0] == '\0') { (void)strcpy(fsa[i].real_hostname[1], fsa[i].host_dsp_name); if (fsa[i].host_toggle == HOST_ONE) { fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[HOST_TWO]; } else { fsa[i].host_dsp_name[(int)fsa[i].toggle_pos] = fsa[i].host_toggle_str[HOST_ONE]; } (void)memcpy(hl[i].real_hostname[1], fsa[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); } } (void)memset(&hl[i].fullname[0], 0, MAX_FILENAME_LENGTH); fsa[i].host_status = 0; fsa[i].error_counter = 0; fsa[i].total_errors = 0; for (k = 0; k < ERROR_HISTORY_LENGTH; k++) { fsa[i].error_history[k] = 0; } fsa[i].jobs_queued = 0; fsa[i].file_counter_done = 0; fsa[i].bytes_send = 0; fsa[i].connections = 0; fsa[i].active_transfers = 0; fsa[i].total_file_counter = 0; fsa[i].total_file_size = 0; fsa[i].special_flag = 0; fsa[i].successful_retries = 0; fsa[i].mc_nack_counter = 0; fsa[i].trl_per_process = fsa[i].transfer_rate_limit; fsa[i].mc_ct_rate_limit = fsa[i].transfer_rate_limit; fsa[i].mc_ctrl_per_process = fsa[i].transfer_rate_limit; fsa[i].debug = NO; fsa[i].host_id = get_str_checksum(fsa[i].host_alias); fsa[i].last_connection = fsa[i].last_retry_time = time(NULL); fsa[i].first_error_time = 0L; fsa[i].start_event_handle = 0L; fsa[i].end_event_handle = 0L; memset(&fsa[i].job_status, 0, size); for (k = 0; k < fsa[i].allowed_transfers; k++) { fsa[i].job_status[k].connect_status = DISCONNECT; fsa[i].job_status[k].proc_id = -1; #ifdef _WITH_BURST_2 fsa[i].job_status[k].job_id = NO_ID; #endif } for (k = fsa[i].allowed_transfers; k < MAX_NO_PARALLEL_JOBS; k++) { fsa[i].job_status[k].no_of_files = -1; fsa[i].job_status[k].proc_id = -1; } } if (hl[i].in_dir_config == YES) { fsa[i].special_flag |= HOST_IN_DIR_CONFIG; hl[i].host_status &= ~HOST_NOT_IN_DIR_CONFIG; } else { fsa[i].special_flag &= ~HOST_IN_DIR_CONFIG; hl[i].host_status |= HOST_NOT_IN_DIR_CONFIG; } if (hl[i].host_status & HOST_CONFIG_HOST_DISABLED) { fsa[i].special_flag |= HOST_DISABLED; } else { fsa[i].special_flag &= ~HOST_DISABLED; } if (hl[i].protocol_options & KEEP_CON_NO_SEND_2) { fsa[i].special_flag |= KEEP_CON_NO_SEND; } else { fsa[i].special_flag &= ~KEEP_CON_NO_SEND; } if (hl[i].protocol_options & KEEP_CON_NO_FETCH_2) { fsa[i].special_flag |= KEEP_CON_NO_FETCH; } else { fsa[i].special_flag &= ~KEEP_CON_NO_FETCH; } if (hl[i].host_status & STOP_TRANSFER_STAT) { fsa[i].host_status |= STOP_TRANSFER_STAT; } else { fsa[i].host_status &= ~STOP_TRANSFER_STAT; } if (hl[i].host_status & PAUSE_QUEUE_STAT) { fsa[i].host_status |= PAUSE_QUEUE_STAT; } else { fsa[i].host_status &= ~PAUSE_QUEUE_STAT; } if (hl[i].host_status & HOST_ERROR_OFFLINE_STATIC) { fsa[i].host_status |= HOST_ERROR_OFFLINE_STATIC; } else { fsa[i].host_status &= ~HOST_ERROR_OFFLINE_STATIC; } if (hl[i].host_status & DO_NOT_DELETE_DATA) { fsa[i].host_status |= DO_NOT_DELETE_DATA; } else { fsa[i].host_status &= ~DO_NOT_DELETE_DATA; } } /* for (i = 0; i < no_of_hosts; i++) */ /* * Check if there is a host entry in the old FSA but NOT in * the HOST_CONFIG. */ if (gotcha != NULL) { if (no_of_gotchas != old_no_of_hosts) { int no_of_new_old_hosts = old_no_of_hosts - no_of_gotchas, j; /* * It could be that some of the new old hosts should be * deleted. The only way to find this out is to see * if they still have files to be send. */ for (j = 0; j < old_no_of_hosts; j++) { if ((gotcha[j] == NO) && (old_fsa[j].total_file_counter == 0)) { /* This host is to be removed! */ no_of_new_old_hosts--; gotcha[j] = YES; } } if (no_of_new_old_hosts > 0) { fsa_size += (no_of_new_old_hosts * sizeof(struct filetransfer_status)); no_of_hosts += no_of_new_old_hosts; /* * Resize the host_list structure if necessary. */ if ((no_of_hosts % HOST_BUF_SIZE) == 0) { size_t new_size, offset; /* Calculate new size for host list. */ new_size = ((no_of_hosts / HOST_BUF_SIZE) + 1) * HOST_BUF_SIZE * sizeof(struct host_list); /* Now increase the space. */ if ((hl = realloc(hl, new_size)) == NULL) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not reallocate memory [%d bytes] for host list : %s", new_size, strerror(errno)); exit(INCORRECT); } /* Initialise the new memory area. */ new_size = HOST_BUF_SIZE * sizeof(struct host_list); offset = (no_of_hosts / HOST_BUF_SIZE) * new_size; memset((char *)hl + offset, 0, new_size); } /* * We now have to make the FSA and host_list structure * larger to store the 'new' hosts. */ ptr = (char *)fsa; ptr -= AFD_WORD_OFFSET; if (fsa_size > 0) { #ifdef HAVE_MMAP if (munmap(ptr, fsa_size) == -1) #else if (msync_emu(ptr) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "msync_emu() error"); } if (munmap_emu(ptr) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to munmap() %s : %s", new_fsa_stat, strerror(errno)); } } if (lseek(fsa_fd, fsa_size - 1, SEEK_SET) == -1) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Failed to lseek() in %s : %s", new_fsa_stat, strerror(errno)); exit(INCORRECT); } if (write(fsa_fd, "", 1) != 1) { system_log(FATAL_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); exit(INCORRECT); } #ifdef HAVE_MMAP if ((ptr = mmap(NULL, fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, fsa_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, new_fsa_stat, 0)) == (caddr_t) -1) #endif { system_log(FATAL_SIGN, __FILE__, __LINE__, "mmap() error : %s", strerror(errno)); exit(INCORRECT); } /* Write new number of hosts to memory mapped region. */ *(int *)ptr = no_of_hosts; /* Reposition fsa pointer after no_of_hosts. */ ptr += AFD_WORD_OFFSET; fsa = (struct filetransfer_status *)ptr; /* * Insert the 'new' old hosts. */ for (j = 0; j < old_no_of_hosts; j++) { if (gotcha[j] == NO) { /* Position the new host there were it was in the old FSA. */ if (j < i) { size_t move_size = (i - j) * sizeof(struct filetransfer_status); (void)memmove(&fsa[j + 1], &fsa[j], move_size); move_size = (i - j) * sizeof(struct host_list); (void)memmove(&hl[j + 1], &hl[j], move_size); } /* Insert 'new' old host in FSA. */ (void)memcpy(&fsa[j], &old_fsa[j], sizeof(struct filetransfer_status)); for (k = 0; k < fsa[j].allowed_transfers; k++) { if (fsa[j].job_status[k].no_of_files == -1) { fsa[j].job_status[k].no_of_files = 0; fsa[j].job_status[k].proc_id = -1; fsa[j].job_status[k].connect_status = DISCONNECT; #ifdef _WITH_BURST_2 fsa[j].job_status[k].job_id = NO_ID; #endif } } for (k = fsa[j].allowed_transfers; k < MAX_NO_PARALLEL_JOBS; k++) { fsa[j].job_status[k].no_of_files = -1; fsa[j].job_status[k].proc_id = -1; } /* Insert 'new' old host in host_list structure. */ (void)memcpy(hl[j].host_alias, fsa[j].host_alias, MAX_HOSTNAME_LENGTH + 1); (void)memcpy(hl[j].real_hostname[0], fsa[j].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[j].real_hostname[1], fsa[j].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(hl[j].proxy_name, fsa[j].proxy_name, MAX_PROXY_NAME_LENGTH + 1); (void)memset(&hl[j].fullname[0], 0, MAX_FILENAME_LENGTH); hl[j].allowed_transfers = fsa[j].allowed_transfers; hl[j].max_errors = fsa[j].max_errors; hl[j].retry_interval = fsa[j].retry_interval; hl[j].transfer_blksize = fsa[j].block_size; hl[j].successful_retries = fsa[j].max_successful_retries; hl[j].file_size_offset = fsa[j].file_size_offset; hl[j].transfer_timeout = fsa[j].transfer_timeout; hl[j].transfer_rate_limit = fsa[j].transfer_rate_limit; hl[j].ttl = fsa[j].ttl; hl[j].socksnd_bufsize = fsa[j].socksnd_bufsize; hl[j].sockrcv_bufsize = fsa[j].sockrcv_bufsize; hl[j].keep_connected = fsa[j].keep_connected; hl[j].warn_time = fsa[j].warn_time; #ifdef WITH_DUP_CHECK hl[j].dup_check_flag = fsa[j].dup_check_flag; hl[j].dup_check_timeout = fsa[j].dup_check_timeout; #endif hl[j].protocol = fsa[j].protocol; hl[j].protocol_options = fsa[j].protocol_options; hl[j].in_dir_config = NO; fsa[j].special_flag &= ~HOST_IN_DIR_CONFIG; hl[j].host_status = 0; if (fsa[j].host_status & HOST_ERROR_OFFLINE_STATIC) { hl[j].host_status |= HOST_ERROR_OFFLINE_STATIC; } if (fsa[j].special_flag & HOST_DISABLED) { hl[j].host_status |= HOST_CONFIG_HOST_DISABLED; } if (fsa[j].special_flag & KEEP_CON_NO_SEND) { hl[j].protocol_options |= KEEP_CON_NO_SEND_2; } if (fsa[j].special_flag & KEEP_CON_NO_FETCH) { hl[j].protocol_options |= KEEP_CON_NO_FETCH_2; } if ((fsa[j].special_flag & HOST_IN_DIR_CONFIG) == 0) { hl[j].host_status |= HOST_NOT_IN_DIR_CONFIG; } if (fsa[j].host_status & STOP_TRANSFER_STAT) { hl[j].host_status |= STOP_TRANSFER_STAT; } if (fsa[j].host_status & PAUSE_QUEUE_STAT) { hl[j].host_status |= PAUSE_QUEUE_STAT; } if (fsa[j].host_toggle == HOST_TWO) { hl[j].host_status |= HOST_TWO_FLAG; } if (fsa[j].host_status & DO_NOT_DELETE_DATA) { hl[j].host_status |= DO_NOT_DELETE_DATA; } i++; } /* if (gotcha[j] == NO) */ } /* for (j = 0; j < old_no_of_hosts; j++) */ } /* if (no_of_new_old_hosts > 0) */ } free(gotcha); } /* Copy configuration information from the old FSA. */ ptr = (char *)fsa - AFD_FEATURE_FLAG_OFFSET_END; *ptr = *((char *)old_fsa - AFD_FEATURE_FLAG_OFFSET_END); } /* Reposition fsa pointer after no_of_hosts. */ ptr = (char *)fsa; ptr -= AFD_WORD_OFFSET; *(ptr + SIZEOF_INT + 1 + 1) = ignore_first_errors; *(ptr + SIZEOF_INT + 1 + 1 + 1) = CURRENT_FSA_VERSION; /* FSA version number. */ if ((pagesize = (int)sysconf(_SC_PAGESIZE)) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to determine the pagesize with sysconf() : %s", strerror(errno)); } *(int *)(ptr + SIZEOF_INT + 4) = pagesize; *(ptr + SIZEOF_INT + 4 + SIZEOF_INT) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 1) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 2) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 3) = 0; /* Not used. */ if (fsa_size > 0) { #ifdef HAVE_MMAP if (munmap(ptr, fsa_size) == -1) #else if (msync_emu(ptr) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "msync_emu() error"); } if (munmap_emu(ptr) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to munmap() %s : %s", new_fsa_stat, strerror(errno)); } } fsa = NULL; /* * Unmap from old memory mapped region. */ if (first_time == NO) { ptr = (char *)old_fsa; ptr -= AFD_WORD_OFFSET; /* Don't forget to unmap old FSA file. */ if (old_fsa_size > 0) { #ifdef HAVE_MMAP if (munmap(ptr, old_fsa_size) == -1) #else if (munmap_emu(ptr) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to munmap() %s : %s", old_fsa_stat, strerror(errno)); } } } /* Remove the old FSA file if there was one. */ if (old_fsa_size > -1) { if (unlink(old_fsa_stat) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to unlink() %s : %s", old_fsa_stat, strerror(errno)); } } /* * Copy the new fsa_id into the locked FSA_ID_FILE file, unlock * and close the file. */ /* Go to beginning in file. */ if (lseek(fsa_id_fd, 0, SEEK_SET) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Could not seek() to beginning of %s : %s", fsa_id_file, strerror(errno)); } /* Write new value into FSA_ID_FILE file. */ if (write(fsa_id_fd, &fsa_id, sizeof(int)) != sizeof(int)) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not write value to FSA ID file : %s", strerror(errno)); exit(INCORRECT); } /* Close and unlock FSA_ID_FILE. */ if (close(fsa_id_fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "close() error : %s", strerror(errno)); } /* Close file with new FSA. */ if (close(fsa_fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "close() error : %s", strerror(errno)); } fsa_fd = -1; /* Close old FSA file. */ if (old_fsa_fd != -1) { if (close(old_fsa_fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "close() error : %s", strerror(errno)); } } (void)write_typesize_data(); return; }
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ main() $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ int main(int argc, char *argv[]) { int fd, *no_of_dir_names, ret; unsigned int search_dir_id; char file[MAX_PATH_LENGTH + FIFO_DIR_LENGTH + DIR_NAME_FILE_LENGTH], *ptr, str_dir_id[MAX_INT_LENGTH + 1], work_dir[MAX_PATH_LENGTH]; struct stat stat_buf; struct dir_name_buf *dnb; if ((get_arg(&argc, argv, "-?", NULL, 0) == SUCCESS) || (get_arg(&argc, argv, "-help", NULL, 0) == SUCCESS) || (get_arg(&argc, argv, "--help", NULL, 0) == SUCCESS)) { usage(argv[0]); exit(SUCCESS); } CHECK_FOR_VERSION(argc, argv); /* First get working directory for the AFD. */ if (get_afd_path(&argc, argv, work_dir) < 0) { exit(INCORRECT); } if (get_arg(&argc, argv, "-d", str_dir_id, MAX_INT_HEX_LENGTH) == INCORRECT) { search_dir_id = 0; str_dir_id[0] = '\0'; } else { search_dir_id = (unsigned int)strtoul(str_dir_id, NULL, 16); } (void)sprintf(file, "%s%s%s", work_dir, FIFO_DIR, DIR_NAME_FILE); if ((fd = open(file, O_RDONLY)) == -1) { (void)fprintf(stderr, _("Failed to open() `%s' : %s (%s %d)\n"), file, strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } if (fstat(fd, &stat_buf) == -1) { (void)fprintf(stderr, _("Failed to fstat() `%s' : %s (%s %d)\n"), file, strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } #ifdef HAVE_MMAP if ((ptr = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0)) == (caddr_t)-1) #else if ((ptr = mmap_emu(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, file, 0)) == (caddr_t)-1) #endif { (void)fprintf(stderr, _("Failed to mmap() `%s' : %s (%s %d)\n"), file, strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } if (close(fd) == -1) { (void)fprintf(stderr, _("Failed to close() `%s' : %s (%s %d)\n"), file, strerror(errno), __FILE__, __LINE__); } no_of_dir_names = (int *)ptr; ptr += AFD_WORD_OFFSET; dnb = (struct dir_name_buf *)ptr; if (*no_of_dir_names > 0) { int i; if (str_dir_id[0] == '\0') { (void)fprintf(stdout, _("No of directories : %d\n"), *no_of_dir_names); (void)fprintf(stdout, "Pos Dir-ID Dir-name [| Original name]\n"); for (i = 0; i < *no_of_dir_names; i++) { if (CHECK_STRCMP(dnb[i].dir_name, dnb[i].orig_dir_name) == 0) { (void)fprintf(stdout, "%-5d %-*x %s\n", i, MAX_INT_LENGTH, dnb[i].dir_id, dnb[i].dir_name); } else { (void)fprintf(stdout, "%-5d %-*x %s | %s\n", i, MAX_INT_LENGTH, dnb[i].dir_id, dnb[i].dir_name, dnb[i].orig_dir_name); } } ret = SUCCESS; } else { for (i = 0; i < *no_of_dir_names; i++) { if (dnb[i].dir_id == search_dir_id) { if (CHECK_STRCMP(dnb[i].dir_name, dnb[i].orig_dir_name) == 0) { (void)fprintf(stdout, "%-5d %-*x %s\n", i, MAX_INT_LENGTH, dnb[i].dir_id, dnb[i].dir_name); } else { (void)fprintf(stdout, "%-5d %-*x %s | %s\n", i, MAX_INT_LENGTH, dnb[i].dir_id, dnb[i].dir_name, dnb[i].orig_dir_name); } exit(SUCCESS); } } (void)fprintf(stdout, _("Directory ID %u not found.\n"), search_dir_id); ret = INCORRECT; } } else { (void)fprintf(stdout, _("No directories.\n")); ret = INCORRECT; } ptr -= AFD_WORD_OFFSET; #ifdef HAVE_MMAP if (munmap(ptr, stat_buf.st_size) == -1) #else if (munmap_emu(ptr) == -1) #endif { (void)fprintf(stderr, _("Failed to munmap() `%s' : %s (%s %d)\n"), file, strerror(errno), __FILE__, __LINE__); } exit(ret); }
/*######################### change_alias_order() ########################*/ void change_alias_order(char **p_host_names, int new_no_of_hosts) { int i, ignore_first_errors, fd, position, pagesize, old_no_of_hosts = no_of_hosts, loop_no_of_hosts, current_fsa_id, new_fsa_fd; off_t new_fsa_size; char *ptr, fsa_id_file[MAX_PATH_LENGTH], new_fsa_stat[MAX_PATH_LENGTH]; struct flock wlock; struct filetransfer_status *new_fsa; if (new_no_of_hosts != -1) { if (no_of_hosts > new_no_of_hosts) { loop_no_of_hosts = no_of_hosts; } else { loop_no_of_hosts = new_no_of_hosts; } no_of_hosts = new_no_of_hosts; } else { loop_no_of_hosts = no_of_hosts; } (void)strcpy(fsa_id_file, p_work_dir); (void)strcat(fsa_id_file, FIFO_DIR); (void)strcat(fsa_id_file, FSA_ID_FILE); wlock.l_type = F_WRLCK; wlock.l_whence = SEEK_SET; wlock.l_start = 0; #ifdef HAVE_MMAP wlock.l_len = fsa_size; #else wlock.l_len = AFD_WORD_OFFSET + (no_of_hosts * sizeof(struct filetransfer_status)); #endif /* HAVE_MMAP */ if (fcntl(fsa_fd, F_SETLKW, &wlock) < 0) { /* Is lock already set or are we setting it again? */ if ((errno != EACCES) && (errno != EAGAIN) && (errno != EBUSY)) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Could not set write lock for FSA_STAT_FILE : %s"), strerror(errno)); } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Could not set write lock for FSA_STAT_FILE : %s"), strerror(errno)); } } /* * When changing the order of the hosts, lock the FSA_ID_FILE so no * one gets the idea to do the same thing or change the DIR_CONFIG * file. */ if ((fd = lock_file(fsa_id_file, ON)) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to lock `%s' [%d]"), fsa_id_file, fd); exit(INCORRECT); } /* Read the fsa_id. */ if (read(fd, ¤t_fsa_id, sizeof(int)) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Could not read the value of the fsa_id : %s"), strerror(errno)); (void)close(fd); exit(INCORRECT); } if (current_fsa_id != fsa_id) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("AAAaaaarrrrghhhh!!! DON'T CHANGE THE DIR_CONFIG FILE WHILE USING edit_hc!!!!")); (void)close(fd); exit(INCORRECT); } current_fsa_id++; /* Mark old FSA as stale. */ *(int *)((char *)fsa - AFD_WORD_OFFSET) = STALE; pagesize = *(int *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT + 4); ignore_first_errors = *(unsigned char *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT + 1 + 1); /* * Create a new FSA with the new ordering of the host aliases. */ (void)snprintf(new_fsa_stat, MAX_PATH_LENGTH, "%s%s%s.%d", p_work_dir, FIFO_DIR, FSA_STAT_FILE, current_fsa_id); /* Now map the new FSA region to a file. */ if ((new_fsa_fd = coe_open(new_fsa_stat, (O_RDWR | O_CREAT | O_TRUNC), FILE_MODE)) < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Failed to open() `%s' : %s"), new_fsa_stat, strerror(errno)); exit(INCORRECT); } new_fsa_size = AFD_WORD_OFFSET + (no_of_hosts * sizeof(struct filetransfer_status)); if (lseek(new_fsa_fd, new_fsa_size - 1, SEEK_SET) == -1) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Failed to lseek() in `%s' : %s"), new_fsa_stat, strerror(errno)); exit(INCORRECT); } if (write(new_fsa_fd, "", 1) != 1) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("write() error : %s"), strerror(errno)); exit(INCORRECT); } #ifdef HAVE_MMAP if ((ptr = mmap(NULL, new_fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, new_fsa_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, new_fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, new_fsa_stat, 0)) == (caddr_t) -1) #endif { system_log(FATAL_SIGN, __FILE__, __LINE__, _("mmap() error : %s"), strerror(errno)); exit(INCORRECT); } /* Write number of hosts to new mmap region. */ *(int *)ptr = no_of_hosts; *(ptr + SIZEOF_INT + 1 + 1) = ignore_first_errors; *(ptr + SIZEOF_INT + 1 + 1 + 1) = CURRENT_FSA_VERSION; /* FSA version number. */ *(int *)(ptr + SIZEOF_INT + 4) = pagesize; *(ptr + SIZEOF_INT + 4 + SIZEOF_INT) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 1) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 2) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 3) = 0; /* Not used. */ /* Copy configuration information from the old FSA. */ ptr += AFD_WORD_OFFSET; *((char *)ptr - AFD_FEATURE_FLAG_OFFSET_END) = *((char *)fsa - AFD_FEATURE_FLAG_OFFSET_END); /* Reposition fsa pointer after no_of_host. */ new_fsa = (struct filetransfer_status *)ptr; if (fra_attach() != SUCCESS) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Failed to attach to FRA.")); exit(INCORRECT); } /* * Now copy each entry from the old FSA to the new FSA in * the order they are found in the host_list_w. */ for (i = 0; i < loop_no_of_hosts; i++) { if (p_host_names[i][0] != '\0') { if ((position = get_host_position(fsa, p_host_names[i], old_no_of_hosts)) < 0) { if (hl != NULL) { int k; /* * Hmmm. This host is not in the FSA. So lets assume this * is a new host. */ (void)memset(&new_fsa[i], 0, sizeof(struct filetransfer_status)); (void)memcpy(new_fsa[i].host_alias, hl[i].host_alias, MAX_HOSTNAME_LENGTH + 1); new_fsa[i].host_id = get_str_checksum(new_fsa[i].host_alias); (void)snprintf(new_fsa[i].host_dsp_name, MAX_HOSTNAME_LENGTH + 2, "%-*s", MAX_HOSTNAME_LENGTH, hl[i].host_alias); new_fsa[i].toggle_pos = strlen(new_fsa[i].host_alias); (void)memcpy(new_fsa[i].real_hostname[0], hl[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(new_fsa[i].real_hostname[1], hl[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); new_fsa[i].host_toggle = HOST_ONE; if (hl[i].host_toggle_str[0] != '\0') { (void)memcpy(new_fsa[i].host_toggle_str, hl[i].host_toggle_str, MAX_TOGGLE_STR_LENGTH); if (hl[i].host_toggle_str[0] == AUTO_TOGGLE_OPEN) { new_fsa[i].auto_toggle = ON; } else { new_fsa[i].auto_toggle = OFF; } new_fsa[i].original_toggle_pos = DEFAULT_TOGGLE_HOST; new_fsa[i].host_dsp_name[(int)new_fsa[i].toggle_pos] = hl[i].host_toggle_str[(int)new_fsa[i].original_toggle_pos]; } else { new_fsa[i].host_toggle_str[0] = '\0'; new_fsa[i].original_toggle_pos = NONE; new_fsa[i].auto_toggle = OFF; } (void)memcpy(new_fsa[i].proxy_name, hl[i].proxy_name, MAX_PROXY_NAME_LENGTH + 1); new_fsa[i].transfer_rate_limit = hl[i].transfer_rate_limit; new_fsa[i].allowed_transfers = hl[i].allowed_transfers; for (k = 0; k < new_fsa[i].allowed_transfers; k++) { new_fsa[i].job_status[k].connect_status = DISCONNECT; new_fsa[i].job_status[k].proc_id = -1; #ifdef _WITH_BURST_2 new_fsa[i].job_status[k].job_id = NO_ID; #endif } for (k = new_fsa[i].allowed_transfers; k < MAX_NO_PARALLEL_JOBS; k++) { new_fsa[i].job_status[k].no_of_files = -1; new_fsa[i].job_status[k].proc_id = -1; } new_fsa[i].max_errors = hl[i].max_errors; new_fsa[i].retry_interval = hl[i].retry_interval; new_fsa[i].block_size = hl[i].transfer_blksize; new_fsa[i].max_successful_retries = hl[i].successful_retries; new_fsa[i].file_size_offset = hl[i].file_size_offset; new_fsa[i].transfer_timeout = hl[i].transfer_timeout; new_fsa[i].protocol = hl[i].protocol; new_fsa[i].protocol_options = hl[i].protocol_options; new_fsa[i].ttl = hl[i].ttl; new_fsa[i].special_flag = 0; if (hl[i].host_status & HOST_CONFIG_HOST_DISABLED) { new_fsa[i].special_flag |= HOST_DISABLED; } new_fsa[i].host_status = 0; if (hl[i].host_status & STOP_TRANSFER_STAT) { new_fsa[i].host_status |= STOP_TRANSFER_STAT; } if (hl[i].host_status & PAUSE_QUEUE_STAT) { new_fsa[i].host_status |= PAUSE_QUEUE_STAT; } } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("AAAaaaarrrrghhhh!!! Could not find hostname `%s'"), p_host_names[i]); (void)close(fd); exit(INCORRECT); } } else { if ((position != INCORRECT) && (position != i)) { int k; for (k = 0; k < no_of_dirs; k++) { if ((fra[k].host_alias[0] != '\0') && (CHECK_STRCMP(fra[k].host_alias, fsa[position].host_alias) == 0)) { fra[k].fsa_pos = i; } } } (void)memcpy(&new_fsa[i], &fsa[position], sizeof(struct filetransfer_status)); } } } #ifdef HAVE_MMAP if (msync(ptr - AFD_WORD_OFFSET, new_fsa_size, MS_SYNC) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, "msync() error : %s", strerror(errno)); } #endif if (fra_detach() < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to detach from FRA.")); } if (fsa_detach(NO) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to detach from old FSA.")); } /* Now "attach" to the new FSA. */ fsa = new_fsa; fsa_fd = new_fsa_fd; fsa_id = current_fsa_id; #ifdef HAVE_MMAP fsa_size = new_fsa_size; #endif /* Go to beginning in file. */ if (lseek(fd, 0, SEEK_SET) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Could not seek() to beginning of `%s' : %s"), fsa_id_file, strerror(errno)); } /* Write new value into FSA_ID_FILE file. */ if (write(fd, &fsa_id, sizeof(int)) != sizeof(int)) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Could not write value to FSA ID file : %s"), strerror(errno)); exit(INCORRECT); } /* Release the lock. */ if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("close() error : %s"), strerror(errno)); } /* Remove the old FSA file. */ (void)snprintf(new_fsa_stat, MAX_PATH_LENGTH, "%s%s%s.%d", p_work_dir, FIFO_DIR, FSA_STAT_FILE, current_fsa_id - 1); if (unlink(new_fsa_stat) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("unlink() error : %s"), strerror(errno)); } return; }
/*############################ init_aftp() ##############################*/ int init_aftp(int argc, char *argv[], struct data *p_db) { int correct = YES, /* Was input/syntax correct? */ set_extended_mode = NO; char *ptr; ptr = argv[0] + strlen(argv[0]) - 1; while ((*ptr != '/') && (ptr != &argv[0][0])) { ptr--; } if (*ptr == '/') { ptr++; } (void)my_strncpy(name, ptr, 30); if (name[0] == 'r') { p_db->exec_mode = RETRIEVE_MODE; } else if (name[0] == 't') { p_db->exec_mode = TEST_MODE; } else { p_db->exec_mode = TRANSFER_MODE; } /* First initialize all values with default values. */ p_db->file_size_offset = -1; /* No appending. */ p_db->blocksize = DEFAULT_TRANSFER_BLOCKSIZE; p_db->remote_dir[0] = '\0'; p_db->hostname[0] = '\0'; p_db->lock = DOT; p_db->lock_notation[0] = '.'; p_db->lock_notation[1] = '\0'; p_db->transfer_mode = 'I'; p_db->ftp_mode = ACTIVE_MODE; #ifdef FTP_CTRL_KEEP_ALIVE_INTERVAL p_db->keepalive = NO; #endif p_db->port = DEFAULT_FTP_PORT; (void)strcpy(p_db->user, DEFAULT_AFD_USER); (void)strcpy(p_db->password, DEFAULT_AFD_PASSWORD); p_db->remove = NO; p_db->transfer_timeout = DEFAULT_TRANSFER_TIMEOUT; p_db->verbose = NO; p_db->append = NO; #ifdef WITH_SSL p_db->auth = NO; #endif p_db->create_target_dir = NO; p_db->dir_mode_str[0] = '\0'; if (name[0] == 't') { p_db->no_of_files = 1; p_db->dummy_size = DEFAULT_TRANSFER_BLOCKSIZE; } else { p_db->no_of_files = 0; } p_db->filename = NULL; p_db->realname = NULL; p_db->sndbuf_size = 0; p_db->rcvbuf_size = 0; p_db->proxy_name[0] = '\0'; /* Evaluate all arguments with '-'. */ while ((--argc > 0) && ((*++argv)[0] == '-')) { switch (*(argv[0] + 1)) { case 'A' : /* Search for file localy for appending. */ p_db->append = YES; break; case 'a' : /* Remote file size offset for appending. */ if ((argc == 1) || ((*(argv + 1)[0] == '-') && ((argv + 1)[0][1] != '2'))) { (void)fprintf(stderr, _("ERROR : No file size offset specified for option -a.\n")); correct = NO; } else { if ((name[0] == 'r') || (name[0] == 't')) { (void)fprintf(stderr, _("ERROR : This option is only for %s.\n"), &name[1]); correct = NO; } else { p_db->file_size_offset = (signed char)atoi(*(argv + 1)); } argc--; argv++; } break; case 'b' : /* FTP transfer block size. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No block size specified for option -b.\n")); correct = NO; } else { p_db->blocksize = atoi(*(argv + 1)); argc--; argv++; } break; case 'c' : /* Configuration file for user, passwd, etc. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No config file specified for option -c.\n")); correct = NO; } else { char config_file[MAX_PATH_LENGTH]; argv++; (void)my_strncpy(config_file, argv[0], MAX_PATH_LENGTH); argc--; eval_config_file(config_file, p_db); } break; case 'C' : /* Create target dir. */ p_db->create_target_dir = YES; if ((argc > 1) && (*(argv + 1)[0] != '-')) { int i = 0; char *aptr; aptr = argv[1]; do { if ((isdigit((int)*aptr)) && (i < 4)) { p_db->dir_mode_str[i] = *aptr; i++; aptr++; } else { i = 0; p_db->dir_mode_str[0] = '\0'; break; } } while (*aptr != '\0'); if (i > 0) { argv++; argc--; p_db->dir_mode_str[i] = '\0'; } } break; case 'd' : /* Target directory on remote host. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No target directory for option -d.\n")); correct = NO; } else { argv++; (void)my_strncpy(p_db->remote_dir, argv[0], MAX_PATH_LENGTH); argc--; } break; case 'f' : /* Configuration file for filenames. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No filename file specified for option -f.\n")); correct = NO; } else { char filename_file[MAX_PATH_LENGTH]; argv++; (void)my_strncpy(filename_file, argv[0], MAX_PATH_LENGTH); argc--; if (eval_filename_file(filename_file, p_db) == INCORRECT) { exit(FILE_NAME_FILE_ERROR); } } break; #ifdef FTP_CTRL_KEEP_ALIVE_INTERVAL case 'k' : /* Keep control connection alive. */ p_db->keepalive = YES; break; #endif case 'h' : /* Remote host name. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No host name or IP number specified for option -h.\n")); correct = NO; } else { argv++; (void)my_strncpy(p_db->hostname, argv[0], MAX_FILENAME_LENGTH); argc--; } break; case 'l' : /* Lock type. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No lock type specified for option -l.\n")); correct = NO; } else { argv++; argc--; if (name[0] == 'r') { (void)fprintf(stderr, _("ERROR : This option is only for %s.\n"), &name[1]); correct = NO; } else { /* Check which lock type is specified. */ if (strcmp(argv[0], LOCK_DOT) == 0) { p_db->lock = DOT; } else if (CHECK_STRCMP(ptr, LOCK_DOT_VMS) == 0) { p_db->lock = DOT_VMS; } #ifdef WITH_READY_FILES else if (strcmp(argv[0], READY_FILE_ASCII) == 0) { p_db->lock = READY_A_FILE; } else if (strcmp(argv[0], READY_FILE_BINARY) == 0) { p_db->lock = READY_B_FILE; } #endif /* WITH_READY_FILES */ else if (strcmp(argv[0], LOCK_OFF) == 0) { p_db->lock = OFF; } else { (void)my_strncpy(p_db->lock_notation, argv[0], MAX_FILENAME_LENGTH); } } } break; case 'm' : /* FTP transfer mode. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No transfer mode specified for option -m.\n")); correct = NO; } else { switch (*(argv + 1)[0]) { case 'a': case 'A': /* ASCII mode. */ p_db->transfer_mode = 'A'; argv++; argc--; break; case 'i': case 'I': case 'b': case 'B': /* Bianary mode. */ p_db->transfer_mode = 'I'; argv++; argc--; break; case 'd': case 'D': /* DOS mode. */ p_db->transfer_mode = 'D'; argv++; argc--; break; default : /* Wrong/unknown mode! */ (void)fprintf(stderr, _("ERROR : Unknown FTP transfer mode <%c> specified for option -m.\n"), *(argv + 1)[0]); correct = NO; break; } } break; case 'n' : /* Specify the number of files. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No number of files specified for option -n.\n")); correct = NO; } else { if (name[0] != 't') { char *p_name; if (name[0] == 'r') { p_name = &name[1]; } else { p_name = name; } (void)fprintf(stderr, _("ERROR : This option is only for t%s.\n"), p_name); correct = NO; } else { p_db->no_of_files = atoi(*(argv + 1)); } argc--; argv++; } break; case 'o' : /* Change mode of file. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No mode number specified for option -o.\n")); correct = NO; } else { int n; ptr = *(argv + 1); n = 0; while ((*ptr != '\n') && (*ptr != '\0') && (n < 4) && (isdigit((int)(*ptr)))) { p_db->chmod_str[n] = *ptr; ptr++; n++; } if (n > 1) { p_db->chmod_str[n] = '\0'; } else { (void)fprintf(stderr, _("ERROR : Not a correct mode number for option -o.\n")); correct = NO; } argc--; argv++; } break; case 'p' : /* Remote TCP port number. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No port number specified for option -p.\n")); correct = NO; } else { p_db->port = atoi(*(argv + 1)); argc--; argv++; } break; case 'P' : /* Use the given proxy procedure to login. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No proxy procedure for option -P.\n")); correct = NO; } else { argv++; (void)my_strncpy(p_db->proxy_name, argv[0], MAX_PROXY_NAME_LENGTH + 1); argc--; } break; case 'u' : /* User name and password for remote login. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No user and password specified for option -u.\n")); correct = NO; } else { argv++; (void)my_strncpy(p_db->user, argv[0], MAX_USER_NAME_LENGTH); argc--; /* If user is specified a password must be there as well! */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No password specified for option -u.\n")); correct = NO; } else { argv++; (void)my_strncpy(p_db->password, argv[0], MAX_USER_NAME_LENGTH); argc--; } } break; case 'r' : /* Remove file that was transmitted. */ p_db->remove = YES; break; case 'R' : /* Socket receive buffer. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No buffer size specified for option -R.\n")); correct = NO; } else { p_db->rcvbuf_size = atoi(*(argv + 1)); argc--; argv++; } break; case 'S' : /* Socket send buffer. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No buffer size specified for option -S.\n")); correct = NO; } else { p_db->sndbuf_size = atoi(*(argv + 1)); argc--; argv++; } break; case 's' : /* Dummy file size. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No file size specified for option -s.\n")); correct = NO; } else { if (name[0] != 't') { char *p_name; if (name[0] == 'r') { p_name = &name[1]; } else { p_name = name; } (void)fprintf(stderr, _("ERROR : This option is only for t%s.\n"), p_name); correct = NO; } else { p_db->dummy_size = atoi(*(argv + 1)); } argc--; argv++; } break; case 't' : /* FTP timeout. */ if ((argc == 1) || (*(argv + 1)[0] == '-')) { (void)fprintf(stderr, _("ERROR : No timeout specified for option -t.\n")); correct = NO; } else { p_db->transfer_timeout = atol(*(argv + 1)); argc--; argv++; } break; case 'v' : /* Verbose mode. */ p_db->verbose = YES; break; case 'x' : /* Use passive mode instead of active mode. */ p_db->ftp_mode = PASSIVE_MODE; break; case 'X' : /* Set extended mode. */ set_extended_mode = YES; break; #ifdef WITH_SSL case 'z' : /* SSL/TLS authentification for control connection only. */ p_db->auth = YES; break; case 'Z' : /* SSL/TLS authentification for control and data connection. */ p_db->auth = BOTH; break; #endif case '?' : /* Help. */ usage(); exit(0); default : /* Unknown parameter. */ (void)fprintf(stderr, _("ERROR : Unknown parameter <%c>. (%s %d)\n"), *(argv[0] + 1), __FILE__, __LINE__); correct = NO; break; } /* switch (*(argv[0] + 1)) */ } if ((*argv)[0] != '-') { argc++; argv--; } if (set_extended_mode == YES) { p_db->ftp_mode |= EXTENDED_MODE; } if (p_db->hostname[0] == '\0') { (void)fprintf(stderr, _("ERROR : No host name or IP number specified.\n")); correct = NO; } if ((p_db->no_of_files == 0) && (argc == 0)) { (void)fprintf(stderr, _("ERROR : No files to be send specified.\n")); correct = NO; } else if ((correct == YES) && (argc > 0) && (p_db->no_of_files == 0)) { if (name[0] == 't') { if (p_db->filename == NULL) { RT_ARRAY(p_db->filename, 1, MAX_PATH_LENGTH, char); (void)my_strncpy(p_db->filename[0], argv[1], MAX_PATH_LENGTH); } else { /* Ignore what ever the dummy user has written. */; } }
DESCR__S_M3 /* ** NAME ** get_arg - gets an argument from the command line ** ** SYNOPSIS ** int get_arg(int *argc, char *argv[], char *arg, ** char *buffer, int buf_length) ** int get_arg_array(int *argc, char *argv[], char *arg, ** char ***buffer, int *no_of_elements) ** int get_arg_int_array(int *argc, char *argv[], char *arg, ** unsigned int **buffer, int *no_of_elements) ** ** DESCRIPTION ** The function get_arg() gets the argument 'arg' from the command ** line and if 'buffer' is not NULL will store the next argument in ** 'buffer'. This next argument may NOT start with a '-', otherwise ** INCORRECT will be returned. The arguments will be removed from ** the argument list. ** ** Function get_arg_array() collects all elements of an argument ** into a two dimensional array that it allocates. The caller ** is responsible to free this free this memory with FREE_RT_ARRAY(). ** ** Function get_arg_int_array() collects all elements of an argument ** into a unsigned int array that it allocates. The caller ** is responsible to free this free this memory with free(). ** ** RETURN VALUES ** SUCCESS when the argument was found. Otherwise INCORRECT is ** returned. ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 23.01.2000 H.Kiehl Created ** 20.10.2005 H.Kiehl Added function get_arg_array(). ** 25.03.2011 H.Kiehl Added function get_arg_int_array(). ** */ DESCR__E_M3 #include <stdio.h> /* fprintf(), NULL */ #include <string.h> /* strcmp(), strcpy() */ #include <stdlib.h> /* strtoul(), malloc() in RT_ARRAY() macro */ #include <errno.h> /*############################# get_arg() ###############################*/ int get_arg(int *argc, char *argv[], char *arg, char *buffer, int buf_length) { register int i; for (i = 1; i < *argc; i++) { if (CHECK_STRCMP(argv[i], arg) == 0) { if (buffer != NULL) { if (((i + 1) < *argc) && (argv[i + 1][0] != '-')) { /* Check if the buffer is long enough! */ if (buf_length < strlen(argv[i + 1])) { (void)fprintf(stderr, _("Buffer for storing value for argument %s to short! (%s %d)\n"), argv[i], __FILE__, __LINE__); return(INCORRECT); } (void)strcpy(buffer, argv[i + 1]); if ((i + 2) < *argc) { register int j; for (j = i; j < (*argc - 2); j++) { argv[j] = argv[j + 2]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 2; return(SUCCESS); } else { /* Either there are not enough arguments or the next */ /* argument starts with a dash '-'. */ return(INCORRECT); } } if ((i + 1) < *argc) { register int j; for (j = i; j < *argc; j++) { argv[j] = argv[j + 1]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 1; return(SUCCESS); } } /* Argument NOT found. */ return(INCORRECT); }
/*########################### get_arg_array() ############################*/ int get_arg_array(int *argc, char *argv[], char *arg, char ***buffer, int *no_of_elements) { register int i; for (i = 1; i < *argc; i++) { if (CHECK_STRCMP(argv[i], arg) == 0) { register int j; int max_length = 0, tmp_i = i; *no_of_elements = 0; max_length = 0; while (((i + 1) < *argc) && (argv[i + 1][0] != '-')) { j = 0; while (argv[i + 1][j] != '\0') { j++; } if (j > max_length) { max_length = j; } (*no_of_elements)++; i++; } if (*no_of_elements > 0) { i = tmp_i; max_length++; RT_ARRAY(*buffer, *no_of_elements, max_length, char); for (j = 0; j < *no_of_elements; j++) { (void)strcpy((*buffer)[j], argv[i + j + 1]); } if ((i + *no_of_elements + 1) < *argc) { for (j = i; j < (*argc - *no_of_elements - 1); j++) { argv[j] = argv[j + *no_of_elements + 1]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= (*no_of_elements + 1); } else { *buffer = NULL; if ((i + 1) < *argc) { for (j = i; j < *argc; j++) { argv[j] = argv[j + 1]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 1; } return(SUCCESS); }
/*########################### link_files() ##############################*/ int link_files(char *src_file_path, char *dest_file_path, int dest_file_path_length, time_t current_time, #ifdef _WITH_PTHREAD off_t *file_size_pool, time_t *file_mtime_pool, char **file_name_pool, unsigned char *file_length_pool, #endif #if defined (_MAINTAINER_LOG) && defined (SHOW_FILE_MOVING) char *caller, int line, #endif struct directory_entry *p_de, struct instant_db *p_db, unsigned int *split_job_counter, int unique_number, int pos_in_fm, int no_of_files, char *unique_name, /* Storage to return unique name. */ off_t *file_size_linked) { int files_linked = 0, #ifdef _DISTRIBUTION_LOG dist_type, #endif retstat; register int i, j; time_t pmatch_time; char *p_src, *p_dest = NULL, *p_dest_end = NULL; *file_size_linked = 0; p_src = src_file_path + strlen(src_file_path); for (i = 0; i < no_of_files; i++) { for (j = 0; j < p_de->fme[pos_in_fm].nfm; j++) { if (p_de->paused_dir == NULL) { pmatch_time = current_time; } else { pmatch_time = file_mtime_pool[i]; } if ((retstat = pmatch(p_de->fme[pos_in_fm].file_mask[j], file_name_pool[i], &pmatch_time)) == 0) { time_t diff_time = current_time - file_mtime_pool[i]; if (diff_time < 0) { diff_time = 0; } if ((p_db->age_limit > 0) && ((fsa[p_db->position].host_status & DO_NOT_DELETE_DATA) == 0) && (diff_time > p_db->age_limit)) { #ifdef _DELETE_LOG size_t dl_real_size; (void)memcpy(dl.file_name, file_name_pool[i], (size_t)(file_length_pool[i] + 1)); (void)snprintf(dl.host_name, MAX_HOSTNAME_LENGTH + 4 + 1, "%-*s %03x", MAX_HOSTNAME_LENGTH, p_db->host_alias, AGE_INPUT); *dl.file_size = file_size_pool[i]; *dl.dir_id = p_de->dir_id; *dl.job_id = p_db->job_id; *dl.input_time = 0L; *dl.split_job_counter = 0; *dl.unique_number = 0; *dl.file_name_length = file_length_pool[i]; dl_real_size = *dl.file_name_length + dl.size + snprintf((dl.file_name + *dl.file_name_length + 1), MAX_FILENAME_LENGTH + 1, # if SIZEOF_TIME_T == 4 "%s%c>%ld (%s %d)", # else "%s%c>%lld (%s %d)", # endif DIR_CHECK, SEPARATOR_CHAR, (pri_time_t)diff_time, __FILE__, __LINE__); if (write(dl.fd, dl.data, dl_real_size) != dl_real_size) { system_log(ERROR_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); } #endif if (p_de->flag & RENAME_ONE_JOB_ONLY) { (void)memcpy(p_src, file_name_pool[i], (size_t)(file_length_pool[i] + 1)); if (unlink(src_file_path) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to unlink() file `%s' : %s", src_file_path, strerror(errno)); } } #ifdef _DISTRIBUTION_LOG dist_type = AGE_LIMIT_DELETE_DIS_TYPE; #endif } else { /* Only create a unique name and the corresponding */ /* directory when we have found a file that is to */ /* be distributed. */ if (p_dest == NULL) { if (p_db->loptions != NULL) { /* Create a new message name and directory. */ if (create_name(dest_file_path, dest_file_path_length, p_db->priority, current_time, p_db->job_id, split_job_counter, &unique_number, unique_name, MAX_FILENAME_LENGTH - 1, -1) < 0) { if (errno == ENOSPC) { system_log(ERROR_SIGN, __FILE__, __LINE__, "DISK FULL!!! Will retry in %d second interval.", DISK_FULL_RESCAN_TIME); while (errno == ENOSPC) { (void)sleep(DISK_FULL_RESCAN_TIME); errno = 0; if (create_name(dest_file_path, dest_file_path_length, p_db->priority, current_time, p_db->job_id, split_job_counter, &unique_number, unique_name, MAX_FILENAME_LENGTH - 1, -1) < 0) { if (errno != ENOSPC) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Failed to create a unique name : %s", strerror(errno)); exit(INCORRECT); } } } system_log(INFO_SIGN, __FILE__, __LINE__, "Continuing after disk was full."); } else { system_log(FATAL_SIGN, __FILE__, __LINE__, "Failed to create a unique name : %s", strerror(errno)); exit(INCORRECT); } } p_dest_end = dest_file_path + strlen(dest_file_path); if (*(p_dest_end - 1) != '/') { *p_dest_end = '/'; p_dest_end++; } (void)strcpy(p_dest_end, unique_name); p_dest = p_dest_end + strlen(unique_name); *(p_dest++) = '/'; *p_dest = '\0'; } else { int dir_no; if ((dir_no = get_dir_number(dest_file_path, p_db->job_id, NULL)) == INCORRECT) { if (p_dest_end != NULL) { *p_dest_end = '\0'; } if (p_src != NULL) { *p_src = '\0'; } return(INCORRECT); } p_dest_end = dest_file_path + strlen(dest_file_path); if (*(p_dest_end - 1) == '/') { p_dest_end--; } (void)snprintf(unique_name, MAX_FILENAME_LENGTH - 1, #if SIZEOF_TIME_T == 4 "%x/%x/%lx_%x_%x", #else "%x/%x/%llx_%x_%x", #endif p_db->job_id, dir_no, (pri_time_t)current_time, unique_number, *split_job_counter); p_dest = p_dest_end + snprintf(p_dest_end, MAX_PATH_LENGTH - (dest_file_path - p_dest_end), "/%s/", unique_name); if (mkdir(dest_file_path, DIR_MODE) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to create directory %s : %s", dest_file_path, strerror(errno)); if (p_dest_end != NULL) { *p_dest_end = '\0'; } if (p_src != NULL) { *p_src = '\0'; } return(INCORRECT); } } } (void)memcpy(p_src, file_name_pool[i], (size_t)(file_length_pool[i] + 1)); (void)memcpy(p_dest, file_name_pool[i], (size_t)(file_length_pool[i] + 1)); #if defined (_MAINTAINER_LOG) && defined (SHOW_FILE_MOVING) maintainer_log(DEBUG_SIGN, NULL, 0, "link_files() [%s %d]: `%s' -> `%s'", caller, line, src_file_path, dest_file_path); #endif /* Rename/link/copy the file. */ if (p_de->flag & RENAME_ONE_JOB_ONLY) { if ((retstat = rename(src_file_path, dest_file_path)) == -1) { int gotcha = NO; /* * It can happen that when we copied/renamed the file * from its source directory into our internal pool * directory, that we have copied/renamed the same * file twice, overwritting one. But in our array * file_name_pool[] we still have both listed. Search * through the array and see if this is the case, then * we can savely ignore this error message. */ if (i > 0) { int k; for (k = 0; k < i; k++) { if (CHECK_STRCMP(file_name_pool[i], file_name_pool[k]) == 0) { system_log(DEBUG_SIGN, NULL, 0, "File %s has been picked up more then once while scanning input directory %s [%s %x]\n", file_name_pool[i], p_de->dir, p_de->alias, p_de->dir_id); gotcha = YES; break; } } } if (gotcha == NO) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to rename() file %s to %s : %s", src_file_path, dest_file_path, strerror(errno)); if (errno == ENOENT) { char whats_gone[40]; whats_gone[0] = '\0'; if (eaccess(src_file_path, R_OK) != 0) { (void)strcat(whats_gone, "src file"); } if (eaccess(dest_file_path, R_OK) != 0) { (void)strcat(whats_gone, ", dst file"); } *p_src = '\0'; *p_dest = '\0'; if (eaccess(src_file_path, R_OK) != 0) { (void)strcat(whats_gone, ", src dir"); } if (eaccess(dest_file_path, R_OK) != 0) { (void)strcat(whats_gone, ", dst dir"); } system_log(DEBUG_SIGN, NULL, 0, "%s is not there", whats_gone); } } } } #ifdef LINUX else if ((p_db->lfs & DO_NOT_LINK_FILES) || ((hardlinks_protected == YES) && (access(src_file_path, W_OK) != 0))) #else else if (p_db->lfs & DO_NOT_LINK_FILES) #endif { #ifdef LINUX try_copy_file: #endif if ((retstat = copy_file(src_file_path, dest_file_path, NULL)) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to copy file %s to %s", src_file_path, dest_file_path); } } else /* Just link() the files. */ { if ((retstat = link(src_file_path, dest_file_path)) == -1) { if (errno == ENOSPC) { system_log(ERROR_SIGN, __FILE__, __LINE__, "DISK FULL!!! Will retry in %d second interval.", DISK_FULL_RESCAN_TIME); while (errno == ENOSPC) { (void)sleep(DISK_FULL_RESCAN_TIME); errno = 0; if (link(src_file_path, dest_file_path) < 0) { if (errno != ENOSPC) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to link file %s to %s : %s", src_file_path, dest_file_path, strerror(errno)); break; } } } system_log(INFO_SIGN, __FILE__, __LINE__, "Continuing after disk was full."); } else { int tmp_errno = errno; #ifdef _DELETE_LOG size_t dl_real_size; #endif #ifdef LINUX if ((tmp_errno == EPERM) && (hardlinks_protected == NEITHER)) { system_log(WARN_SIGN, __FILE__, __LINE__, "Hardlinks are protected! You need to unset this in /proc/sys/fs/protected_hardlinks. Otherwise AFD must copy files!"); hardlinks_protected = YES; goto try_copy_file; } #endif system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to link file %s to %s : %s", src_file_path, dest_file_path, strerror(tmp_errno)); #ifdef _DELETE_LOG (void)memcpy(dl.file_name, file_name_pool[i], (size_t)(file_length_pool[i] + 1)); (void)snprintf(dl.host_name, MAX_HOSTNAME_LENGTH + 4 + 1, "%-*s %03x", MAX_HOSTNAME_LENGTH, p_db->host_alias, INTERNAL_LINK_FAILED); *dl.file_size = file_size_pool[i]; *dl.dir_id = p_de->dir_id; *dl.job_id = p_db->job_id; *dl.input_time = 0L; *dl.split_job_counter = 0; *dl.unique_number = 0; *dl.file_name_length = file_length_pool[i]; dl_real_size = *dl.file_name_length + dl.size + snprintf((dl.file_name + *dl.file_name_length + 1), MAX_FILENAME_LENGTH + 1, "%s%c>%s (%s %d)", DIR_CHECK, SEPARATOR_CHAR, strerror(tmp_errno), __FILE__, __LINE__); if (write(dl.fd, dl.data, dl_real_size) != dl_real_size) { system_log(ERROR_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); } #endif } } } if (retstat != -1) { #ifndef _WITH_PTHREAD if ((files_linked % FILE_NAME_STEP_SIZE) == 0) { size_t new_size; /* Calculate new size of file name buffer. */ new_size = ((files_linked / FILE_NAME_STEP_SIZE) + 1) * FILE_NAME_STEP_SIZE * MAX_FILENAME_LENGTH; /* Increase the space for the file name buffer. */ if ((file_name_buffer = realloc(file_name_buffer, new_size)) == NULL) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not realloc() memory : %s", strerror(errno)); exit(INCORRECT); } /* Calculate new size of file size buffer. */ new_size = ((files_linked / FILE_NAME_STEP_SIZE) + 1) * FILE_NAME_STEP_SIZE * sizeof(off_t); /* Increase the space for the file size buffer. */ if ((file_size_buffer = realloc(file_size_buffer, new_size)) == NULL) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not realloc() memory : %s", strerror(errno)); exit(INCORRECT); } } (void)memcpy((file_name_buffer + (files_linked * MAX_FILENAME_LENGTH)), file_name_pool[i], (size_t)(file_length_pool[i] + 1)); file_size_buffer[files_linked] = file_size_pool[i]; #endif files_linked++; *file_size_linked += file_size_pool[i]; #ifdef _DISTRIBUTION_LOG dist_type = NORMAL_DIS_TYPE; #endif } #ifdef _DISTRIBUTION_LOG else { dist_type = ERROR_DIS_TYPE; } #endif } #ifdef _DISTRIBUTION_LOG if ((dist_type < NO_OF_DISTRIBUTION_TYPES) && (file_dist_pool[i][dist_type].no_of_dist < max_jobs_per_file)) { file_dist_pool[i][dist_type].jid_list[file_dist_pool[i][dist_type].no_of_dist] = p_db->job_id; file_dist_pool[i][dist_type].proc_cycles[file_dist_pool[i][dist_type].no_of_dist] = (unsigned char)(p_db->no_of_loptions - p_db->no_of_time_entries); file_dist_pool[i][dist_type].no_of_dist++; } #endif /* * Since the file is already in the file directory * no need to test any further filters. */ break; } else if (retstat == 1) { /* * This file is definitely NOT wanted, no matter what the * following filters say. */ break; } } /* for (j = 0; j < p_de->fme[pos_in_fm].nfm; j++) */
/*######################### check_fake_user() ###########################*/ void check_fake_user(int *argc, char *argv[], char *config_file, char *fake_user) { register int i; char wanted_user[MAX_FULL_USER_ID_LENGTH]; wanted_user[0] = 1; for (i = 1; i < *argc; i++) { if (CHECK_STRCMP(argv[i], "-u") == 0) { if (((i + 1) < *argc) && (argv[i + 1][0] != '-')) { /* Check if the buffer is long enough! */ if (MAX_FULL_USER_ID_LENGTH < strlen(argv[i + 1])) { (void)fprintf(stderr, _("Buffer for storing fake user to short. (%s %d)\n"), __FILE__, __LINE__); fake_user[0] = '\0'; return; } (void)strcpy(wanted_user, argv[i + 1]); if ((i + 2) < *argc) { register int j; for (j = i; j < *argc; j++) { argv[j] = argv[j + 2]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 2; i = *argc; } else { /* No fake user supplied, so lets take it from */ /* config file. */ wanted_user[0] = '\0'; if ((i + 1) < *argc) { register int j; for (j = i; j < *argc; j++) { argv[j] = argv[j + 1]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 1; i = *argc; } break; } } if (wanted_user[0] != 1) { struct passwd *pwd; if ((pwd = getpwuid(getuid())) != NULL) { char *buffer = NULL, full_config_name[MAX_PATH_LENGTH]; (void)snprintf(full_config_name, MAX_PATH_LENGTH, "%s%s%s", p_work_dir, ETC_DIR, config_file); if ((eaccess(full_config_name, F_OK) == 0) && (read_file_no_cr(full_config_name, &buffer, YES, __FILE__, __LINE__) != INCORRECT)) { char fake_user_list[MAX_PATH_LENGTH]; if (get_definition(buffer, FAKE_USER_DEF, fake_user_list, MAX_PATH_LENGTH) != NULL) { size_t length; length = strlen(pwd->pw_name); if (length > 0) { int change_char; char real_user[MAX_FULL_USER_ID_LENGTH + 2], *ptr, *tmp_ptr; if ((length + 1) < MAX_FULL_USER_ID_LENGTH) { (void)memcpy(real_user, pwd->pw_name, length); } else { (void)memcpy(real_user, pwd->pw_name, MAX_FULL_USER_ID_LENGTH - 1); length = MAX_FULL_USER_ID_LENGTH - 1; } real_user[length] = '-'; real_user[length + 1] = '>'; real_user[length + 2] = '\0'; ptr = fake_user_list; while ((ptr = lposi(ptr, real_user, length + 2)) != NULL) { ptr--; tmp_ptr = ptr; while ((*tmp_ptr != ',') && (*tmp_ptr != '\0')) { tmp_ptr++; } if (*tmp_ptr == ',') { change_char = YES; *tmp_ptr = '\0'; } else { change_char = NO; } if ((wanted_user[0] == '\0') || (CHECK_STRCMP(ptr, wanted_user) == 0)) { i = 0; while ((*(ptr + i) != ' ') && (*(ptr + i) != '\0') && (*(ptr + i) != '\t') && (i < MAX_FULL_USER_ID_LENGTH)) { fake_user[i] = *(ptr + i); i++; } fake_user[i] = '\0'; free(buffer); return; } if (change_char == YES) { *tmp_ptr = ','; } ptr = tmp_ptr; } } } } free(buffer); (void)fprintf(stderr, "%s (%s %d)\n", PERMISSION_DENIED_STR, __FILE__, __LINE__); exit(INCORRECT); } } fake_user[0] = '\0'; return; }
/*############################# get_pw() ################################*/ int get_pw(char *uh_name, char *password, int url_conform) { int pwb_fd, ret; char pwb_file_name[MAX_PATH_LENGTH]; (void)strcpy(pwb_file_name, p_work_dir); (void)strcat(pwb_file_name, FIFO_DIR); (void)strcat(pwb_file_name, PWB_DATA_FILE); password[0] = '\0'; if ((pwb_fd = open(pwb_file_name, O_RDONLY)) == -1) { if (errno == ENOENT) { /* * It can be that there are absolutly no passwords in DIR_CONFIG, * so PWB_DATA_FILE is not created. */ ret = SUCCESS; } else { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to open() `%s' : %s"), pwb_file_name, strerror(errno)); ret = INCORRECT; } } else { struct stat stat_buf; #ifdef LOCK_DEBUG rlock_region(pwb_fd, 1, __FILE__, __LINE__); #else rlock_region(pwb_fd, 1); #endif if (fstat(pwb_fd, &stat_buf) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to fstat() `%s' : %s"), pwb_file_name, strerror(errno)); ret = INCORRECT; } else { if (stat_buf.st_size <= AFD_WORD_OFFSET) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Password file %s is not long enough to contain any valid data."), pwb_file_name); ret = INCORRECT; } else { char *ptr; #ifdef HAVE_MMAP if ((ptr = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, pwb_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, pwb_file_name, 0)) == (caddr_t) -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to mmap() `%s' : %s"), pwb_file_name, strerror(errno)); ret = INCORRECT; } else { int digit, i, j, k, no_of_passwd; char str_hex[2]; unsigned char *tmp_ptr; struct passwd_buf *pwb; no_of_passwd = *(int *)ptr; ptr += AFD_WORD_OFFSET; pwb = (struct passwd_buf *)ptr; ret = NONE; /* In case we do not find anything. */ for (i = 0; i < no_of_passwd; i++) { if (CHECK_STRCMP(uh_name, pwb[i].uh_name) == 0) { tmp_ptr = pwb[i].passwd; j = 0; k = 0; digit = -1; while (*tmp_ptr != '\0') { if ((j % 2) == 0) { password[k] = *tmp_ptr + 24 - j; } else { password[k] = *tmp_ptr + 11 - j; } if (url_conform != YES) { if (password[k] == '%') { digit = 0; } else if (digit != -1) { str_hex[digit] = password[k]; if (digit == 1) { int value = -1; if ((str_hex[0] >= '0') && (str_hex[0] <= '9')) { value = (str_hex[0] - '0') * 16; } else if ((str_hex[0] >= 'a') && (str_hex[0] <= 'f')) { value = ((str_hex[0] - 'a') + 10) * 16; } else if ((str_hex[0] >= 'A') && (str_hex[0] <= 'F')) { value = ((str_hex[0] - 'A') + 10) * 16; } if (value != -1) { if ((str_hex[1] >= '0') && (str_hex[1] <= '9')) { value += (str_hex[1] - '0'); password[k] = value; k++; } else if ((str_hex[1] >= 'a') && (str_hex[1] <= 'f')) { value += ((str_hex[1] - 'a') + 10); password[k] = value; k++; } else if ((str_hex[1] >= 'A') && (str_hex[1] <= 'F')) { value += ((str_hex[1] - 'A') + 10); password[k] = value; k++; } else { password[k] = '%'; password[k + 1] = str_hex[0]; password[k + 2] = str_hex[1]; k += 3; } digit = -1; } else { password[k] = '%'; password[k + 1] = str_hex[0]; k += 2; digit = -1; } } else { digit++; } } else { k++; } } else { k++; } tmp_ptr++; j++; } password[j] = '\0'; ret = SUCCESS; break; } } ptr -= AFD_WORD_OFFSET; #ifdef HAVE_MMAP if (munmap(ptr, stat_buf.st_size) == -1) #else if (munmap_emu(ptr) == -1) #endif { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to munmap() from `%s' : %s"), pwb_file_name, strerror(errno)); } } } } if (close(pwb_fd) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, _("close() error : %s"), strerror(errno)); } } return(ret); }