Beispiel #1
0
bool ConsiderLocalFile(const char *filename, const char *directory)
{
    struct stat stat;
    if (lstat(filename, &stat) == -1)
    {
        return ConsiderFile(filename, directory, NULL);
    }
    else
    {
        return ConsiderFile(filename, directory, &stat);
    }
}
Beispiel #2
0
bool ConsiderAbstractFile(const char *filename, const char *directory, FileCopy fc, AgentConnection *conn)
{
    struct stat stat;
    char buf[CF_BUFSIZE];
    snprintf(buf, sizeof(buf), "%s/%s", filename, directory);
    MapName(buf);

    if (cf_lstat(buf, &stat, fc, conn) == -1)
    {
        return ConsiderFile(filename, directory, NULL);
    }
    else
    {
        return ConsiderFile(filename, directory, &stat);
    }
}
Beispiel #3
0
int DepthSearch(char *name, struct stat *sb, int rlevel, Attributes attr, Promise *pp)
{
    Dir *dirh;
    int goback;
    const struct dirent *dirp;
    char path[CF_BUFSIZE];
    struct stat lsb;

    if (!attr.havedepthsearch)  /* if the search is trivial, make sure that we are in the parent dir of the leaf */
    {
        char basedir[CF_BUFSIZE];

        CfDebug(" -> Direct file reference %s, no search implied\n", name);
        snprintf(basedir, sizeof(basedir), "%s", name);
        ChopLastNode(basedir);
        chdir(basedir);
        return VerifyFileLeaf(name, sb, attr, pp);
    }

    if (rlevel > CF_RECURSION_LIMIT)
    {
        CfOut(cf_error, "", "WARNING: Very deep nesting of directories (>%d deep): %s (Aborting files)", rlevel, name);
        return false;
    }

    if (rlevel > CF_RECURSION_LIMIT)
    {
        CfOut(cf_error, "", "WARNING: Very deep nesting of directories (>%d deep): %s (Aborting files)", rlevel, name);
        return false;
    }

    memset(path, 0, CF_BUFSIZE);

    CfDebug("To iterate is Human, to recurse is Divine...(%s)\n", name);

    if (!PushDirState(name, sb))
    {
        return false;
    }

    if ((dirh = OpenDirLocal(".")) == NULL)
    {
        CfOut(cf_inform, "opendir", "Could not open existing directory %s\n", name);
        return false;
    }

    for (dirp = ReadDir(dirh); dirp != NULL; dirp = ReadDir(dirh))
    {
        if (!ConsiderFile(dirp->d_name, name, attr, pp))
        {
            continue;
        }

        strcpy(path, name);
        AddSlash(path);

        if (!JoinPath(path, dirp->d_name))
        {
            CloseDir(dirh);
            return true;
        }

        if (lstat(dirp->d_name, &lsb) == -1)
        {
            CfOut(cf_verbose, "lstat", "Recurse was looking at %s when an error occurred:\n", path);
            continue;
        }

        if (S_ISLNK(lsb.st_mode))       /* should we ignore links? */
        {
            if (!KillGhostLink(path, attr, pp))
            {
                VerifyFileLeaf(path, &lsb, attr, pp);
            }
            else
            {
                continue;
            }
        }

        /* See if we are supposed to treat links to dirs as dirs and descend */

        if (attr.recursion.travlinks && S_ISLNK(lsb.st_mode))
        {
            if (lsb.st_uid != 0 && lsb.st_uid != getuid())
            {
                CfOut(cf_inform, "",
                      "File %s is an untrusted link: cfengine will not follow it with a destructive operation", path);
                continue;
            }

            /* if so, hide the difference by replacing with actual object */

            if (cfstat(dirp->d_name, &lsb) == -1)
            {
                CfOut(cf_error, "stat", "Recurse was working on %s when this failed:\n", path);
                continue;
            }
        }

        if (attr.recursion.xdev && DeviceBoundary(&lsb, pp))
        {
            CfOut(cf_verbose, "", "Skipping %s on different device - use xdev option to change this\n", path);
            continue;
        }

        if (S_ISDIR(lsb.st_mode))
        {
            if (SkipDirLinks(path, dirp->d_name, attr.recursion))
            {
                continue;
            }

            if (attr.recursion.depth > 1 && rlevel <= attr.recursion.depth)
            {
                CfOut(cf_verbose, "", " ->>  Entering %s (%d)\n", path, rlevel);
                goback = DepthSearch(path, &lsb, rlevel + 1, attr, pp);
                PopDirState(goback, name, sb, attr.recursion);
                VerifyFileLeaf(path, &lsb, attr, pp);
            }
            else
            {
                VerifyFileLeaf(path, &lsb, attr, pp);
            }
        }
        else
        {
            VerifyFileLeaf(path, &lsb, attr, pp);
        }
    }

    CloseDir(dirh);
    return true;
}
Beispiel #4
0
static int VerifyFileSystem(EvalContext *ctx, char *name, Attributes a, Promise *pp)
{
    struct stat statbuf, localstat;
    Dir *dirh;
    const struct dirent *dirp;
    off_t sizeinbytes = 0;
    long filecount = 0;
    char buff[CF_BUFSIZE];

    CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Checking required filesystem %s\n", name);

    if (cfstat(name, &statbuf) == -1)
    {
        return (false);
    }

    if (S_ISLNK(statbuf.st_mode))
    {
        KillGhostLink(ctx, name, a, pp);
        return (true);
    }

    if (S_ISDIR(statbuf.st_mode))
    {
        if ((dirh = DirOpen(name)) == NULL)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "opendir", "Can't open directory %s which checking required/disk\n", name);
            return false;
        }

        for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh))
        {
            if (!ConsiderFile(ctx, dirp->d_name, name, a, pp))
            {
                continue;
            }

            filecount++;

            strcpy(buff, name);

            if (buff[strlen(buff)] != FILE_SEPARATOR)
            {
                strcat(buff, FILE_SEPARATOR_STR);
            }

            strcat(buff, dirp->d_name);

            if (lstat(buff, &localstat) == -1)
            {
                if (S_ISLNK(localstat.st_mode))
                {
                    KillGhostLink(ctx, buff, a, pp);
                    continue;
                }

                CfOut(OUTPUT_LEVEL_ERROR, "lstat", "Can't stat volume %s\n", buff);
                continue;
            }

            sizeinbytes += localstat.st_size;
        }

        DirClose(dirh);

        if (sizeinbytes < 0)
        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Internal error: count of byte size was less than zero!\n");
            return true;
        }

        if (sizeinbytes < a.volume.sensible_size)
        {
            cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_INTERRUPTED, "", pp, a, " !! File system %s is suspiciously small! (%jd bytes)\n", name,
                 (intmax_t) sizeinbytes);
            return (false);
        }

        if (filecount < a.volume.sensible_count)
        {
            cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_INTERRUPTED, "", pp, a, " !! Filesystem %s has only %ld files/directories.\n", name,
                 filecount);
            return (false);
        }
    }

    cfPS(ctx, OUTPUT_LEVEL_INFORM, PROMISE_RESULT_NOOP, "", pp, a, " -> Filesystem %s's content seems to be sensible as promised\n", name);
    return (true);
}
Beispiel #5
0
static bool GetAcpi(double *cf_this)
{
    Dir *dirh;
    FILE *fp;
    const struct dirent *dirp;
    int count = 0;
    char path[CF_BUFSIZE], buf[CF_BUFSIZE], index[4];
    double temp = 0;
    Attributes attr;

    memset(&attr, 0, sizeof(attr));
    attr.transaction.audit = false;

    CfDebug("ACPI temperature\n");

    if ((dirh = OpenDirLocal("/proc/acpi/thermal_zone")) == NULL)
    {
        CfOut(cf_verbose, "opendir", "Can't open directory %s\n", path);
        return false;
    }

    for (dirp = ReadDir(dirh); dirp != NULL; dirp = ReadDir(dirh))
    {
        if (!ConsiderFile(dirp->d_name, path, attr, NULL))
        {
            continue;
        }

        snprintf(path, CF_BUFSIZE, "/proc/acpi/thermal_zone/%s/temperature", dirp->d_name);

        if ((fp = fopen(path, "r")) == NULL)
        {
            printf("Couldn't open %s\n", path);
            continue;
        }

        fgets(buf, CF_BUFSIZE - 1, fp);

        sscanf(buf, "%*s %lf", &temp);

        for (count = 0; count < 4; count++)
        {
            snprintf(index, 2, "%d", count);

            if (strstr(dirp->d_name, index))
            {
                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                CfDebug("Set temp%d to %lf\n", count, temp);
            }
        }
        fclose(fp);
    }

    CloseDir(dirh);
    return true;
}