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); } }
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); } }
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; }
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); }
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; }