Esempio n. 1
0
/*####################### 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);
   }
}
Esempio n. 3
0
/*############################ 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;
}
Esempio n. 4
0
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 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);
}
Esempio n. 5
0
/*######################### 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, &current_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;
}
Esempio n. 6
0
File: init_aftp.c Progetto: hfs/afd
/*############################ 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. */;
              }
           }
Esempio n. 7
0
File: get_arg.c Progetto: hfs/afd
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);
}
Esempio n. 8
0
File: get_arg.c Progetto: hfs/afd
/*########################### 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);
      }
Esempio n. 9
0
/*########################### 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++) */
Esempio n. 10
0
/*######################### 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;
}
Esempio n. 11
0
File: get_pw.c Progetto: hfs/afd
/*############################# 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);
}