예제 #1
0
bool GenericAgentIsPolicyReloadNeeded(const GenericAgentConfig *config, const Policy *policy)
{
    char filename[CF_MAXVARSIZE];

    time_t validated_at = ReadPolicyValidatedFileMTime(config);

    if (validated_at > time(NULL))
    {
        Log(LOG_LEVEL_INFO,
            "Clock seems to have jumped back in time - mtime of '%s' is newer than current time - touching it",
            filename);

        if (utime(filename, NULL) == -1)
        {
            Log(LOG_LEVEL_ERR, "Could not touch '%s'. (utime: %s)", filename, GetErrorStr());
        }
        return true;
    }

    {
        struct stat sb;
        if (stat(config->input_file, &sb) == -1)
        {
            Log(LOG_LEVEL_VERBOSE, "There is no readable input file at '%s'. (stat: %s)", config->input_file, GetErrorStr());
            return true;
        }
        else if (sb.st_mtime > validated_at || sb.st_mtime > config->policy_last_read_attempt)
        {
            Log(LOG_LEVEL_VERBOSE, "Input file '%s' has changed since the last policy read attempt", config->input_file);
            return true;
        }
    }

// Check the directories first for speed and because non-input/data files should trigger an update

    snprintf(filename, CF_MAXVARSIZE, "%s/inputs", CFWORKDIR);
    MapName(filename);

    if (IsNewerFileTree(filename, config->policy_last_read_attempt))
    {
        Log(LOG_LEVEL_VERBOSE, "Quick search detected file changes");
        return true;
    }

    if (policy)
    {
        const LogLevel missing_inputs_log_level = config->ignore_missing_inputs ? LOG_LEVEL_VERBOSE : LOG_LEVEL_ERR;

        StringSet *input_files = PolicySourceFiles(policy);

        StringSetIterator iter = StringSetIteratorInit(input_files);
        const char *input_file = NULL;
        bool reload_needed = false;

        while ((input_file = StringSetIteratorNext(&iter)))
        {
            struct stat sb;
            if (stat(input_file, &sb) == -1)
            {
                Log(missing_inputs_log_level, "Unreadable promise proposals at '%s'. (stat: %s)", input_file, GetErrorStr());
                reload_needed = true;
                break;
            }
            else if (sb.st_mtime > config->policy_last_read_attempt)
            {
                reload_needed = true;
                break;
            }
        }

        StringSetDestroy(input_files);
        if (reload_needed)
        {
            return true;
        }
    }

    {
        snprintf(filename, CF_MAXVARSIZE, "%s/policy_server.dat", CFWORKDIR);
        MapName(filename);

        struct stat sb;
        if ((stat(filename, &sb) != -1) && (sb.st_mtime > config->policy_last_read_attempt))
        {
            return true;
        }
    }

    return false;
}
예제 #2
0
파일: files_names.c 프로젝트: patuchov/core
int IsNewerFileTree(char *dir, time_t reftime)
{
    const struct dirent *dirp;
    char path[CF_BUFSIZE] = { 0 };
    Dir *dirh;
    struct stat sb;

// Assumes that race conditions on the file path are unlikely and unimportant

    if (lstat(dir, &sb) == -1)
    {
        Log(LOG_LEVEL_ERR, "Unable to stat directory '%s' in IsNewerFileTree. (stat: %s)", dir, GetErrorStr());
        // return true to provoke update
        return true;
    }

    if (S_ISDIR(sb.st_mode))
    {
        if (sb.st_mtime > reftime)
        {
            Log(LOG_LEVEL_VERBOSE, " >> Detected change in %s", dir);
            return true;
        }
    }

    if ((dirh = DirOpen(dir)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Unable to open directory '%s' in IsNewerFileTree. (opendir: %s)", dir, GetErrorStr());
        return false;
    }
    else
    {
        for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh))
        {
            if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, ".."))
            {
                continue;
            }

            strncpy(path, dir, CF_BUFSIZE - 1);

            if (!JoinPath(path, dirp->d_name))
            {
                Log(LOG_LEVEL_ERR, "Internal limit: Buffer ran out of space adding %s to %s in IsNewerFileTree", dir,
                    path);
                DirClose(dirh);
                return false;
            }

            if (lstat(path, &sb) == -1)
            {
                Log(LOG_LEVEL_ERR, "Unable to stat directory '%s' in IsNewerFileTree. (lstat: %s)", path, GetErrorStr());
                DirClose(dirh);
                // return true to provoke update
                return true;
            }

            if (S_ISDIR(sb.st_mode))
            {
                if (sb.st_mtime > reftime)
                {
                    Log(LOG_LEVEL_VERBOSE, " >> Detected change in %s", path);
                    DirClose(dirh);
                    return true;
                }
                else
                {
                    if (IsNewerFileTree(path, reftime))
                    {
                        DirClose(dirh);
                        return true;
                    }
                }
            }
        }
    }

    DirClose(dirh);
    return false;
}
예제 #3
0
파일: files_names.c 프로젝트: npe9/core
int IsNewerFileTree(const char *dir, time_t reftime)
{
    const struct dirent *dirp;
    Dir *dirh;
    struct stat sb;

// Assumes that race conditions on the file path are unlikely and unimportant

    if (lstat(dir, &sb) == -1)
    {
        Log(LOG_LEVEL_ERR, "Unable to stat directory '%s' in IsNewerFileTree. (stat: %s)", dir, GetErrorStr());
        // return true to provoke update
        return true;
    }

    if (S_ISDIR(sb.st_mode))
    {
        if (sb.st_mtime > reftime)
        {
            Log(LOG_LEVEL_VERBOSE, " >> Detected change in %s", dir);
            return true;
        }
    }

    if ((dirh = DirOpen(dir)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Unable to open directory '%s' in IsNewerFileTree. (opendir: %s)", dir, GetErrorStr());
        return false;
    }
    else
    {
        for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh))
        {
            if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, ".."))
            {
                continue;
            }

            char path[CF_BUFSIZE];
            size_t ret = (size_t) snprintf(path, sizeof(path), "%s%c%s",
                                           dir, FILE_SEPARATOR, dirp->d_name);

            if (ret >= sizeof(path))
            {
                Log(LOG_LEVEL_ERR,
                    "Internal limit reached in IsNewerFileTree(),"
                    " path too long: '%s' + '%s'",
                    dir, dirp->d_name);
                DirClose(dirh);
                return false;
            }

            if (lstat(path, &sb) == -1)
            {
                Log(LOG_LEVEL_ERR, "Unable to stat directory '%s' in IsNewerFileTree. (lstat: %s)", path, GetErrorStr());
                DirClose(dirh);
                // return true to provoke update
                return true;
            }

            if (S_ISDIR(sb.st_mode))
            {
                if (sb.st_mtime > reftime)
                {
                    Log(LOG_LEVEL_VERBOSE, " >> Detected change in %s", path);
                    DirClose(dirh);
                    return true;
                }
                else
                {
                    if (IsNewerFileTree(path, reftime))
                    {
                        DirClose(dirh);
                        return true;
                    }
                }
            }
        }
    }

    DirClose(dirh);
    return false;
}
예제 #4
0
int NewPromiseProposals()

{ struct Rlist *rp,*sl;
  struct stat sb;
  int result = false;
  char filename[CF_MAXVARSIZE];

if (MINUSF)
   {
   snprintf(filename,CF_MAXVARSIZE,"%s/state/validated_%s",CFWORKDIR,CanonifyName(VINPUTFILE));
   MapName(filename);   
   }
else
   {
   snprintf(filename,CF_MAXVARSIZE,"%s/masterfiles/cf_promises_validated",CFWORKDIR);
   MapName(filename);
   }
  
if (stat(filename,&sb) != -1)
   {
   PROMISETIME = sb.st_mtime;
   }
else
   {
   PROMISETIME = 0;
   }


// sanity check

if(PROMISETIME > time(NULL))
   {
   CfOut(cf_inform, "", "!! Clock seems to have jumped back in time - mtime of %s is newer than current time - touching it", filename);
   
   if(utime(filename,NULL) == -1)
      {
      CfOut(cf_error, "utime", "!! Could not touch %s", filename);
      }

   PROMISETIME = 0;
   return true;
   }

if (cfstat(InputLocation(VINPUTFILE),&sb) == -1)
   {
   CfOut(cf_verbose,"stat","There is no readable input file at %s",VINPUTFILE);
   return true;
   }

if (sb.st_mtime > PROMISETIME)
   {
   CfOut(cf_verbose,""," -> Promises seem to change");
   return true;
   }

// Check the directories first for speed and because non-input/data files should trigger an update

snprintf(filename,CF_MAXVARSIZE,"%s/inputs",CFWORKDIR);
MapName(filename);

if (IsNewerFileTree(filename,PROMISETIME))
   {
   CfOut(cf_verbose,""," -> Quick search detected file changes");
   return true;
   }

// Check files in case there are any abs paths

if (VINPUTLIST != NULL)
   {
   for (rp = VINPUTLIST; rp != NULL; rp=rp->next)
      {
      if (rp->type != CF_SCALAR)
         {
         CfOut(cf_error,"","Non file object %s in list\n",(char *)rp->item);
         }
      else
         {
         struct Rval returnval = EvaluateFinalRval("sys",rp->item,rp->type,true,NULL);

         switch (returnval.rtype)
            {
            case CF_SCALAR:

                if (cfstat(InputLocation((char *)returnval.item),&sb) == -1)
                   {
                   CfOut(cf_error,"stat","Unreadable promise proposals at %s",(char *)returnval.item);
                   result = true;
                   break;
                   }

                if (sb.st_mtime > PROMISETIME)
                   {
                   result = true;
                   }

                break;

            case CF_LIST:

                for (sl = (struct Rlist *)returnval.item; sl != NULL; sl=sl->next)
                   {
                   if (cfstat(InputLocation((char *)sl->item),&sb) == -1)
                      {
                      CfOut(cf_error,"stat","Unreadable promise proposals at %s",(char *)sl->item);
                      result = true;
                      break;
                      }

                   if (sb.st_mtime > PROMISETIME)
                      {
                      result = true;
                      break;
                      }
                   }

                break;
            }

         DeleteRvalItem(returnval.item,returnval.rtype);

         if (result)
            {
            break;
            }
         }
      }
   }

// did policy server change (used in $(sys.policy_hub))?
snprintf(filename,CF_MAXVARSIZE,"%s/policy_server.dat",CFWORKDIR);
MapName(filename);

if ((cfstat(filename,&sb) != -1) && (sb.st_mtime > PROMISETIME))
   {
   result = true;
   }

return result | ALWAYS_VALIDATE;
}