Attached are patches for various bugs and new features to cfengine. All
patches are against cfengine 3.0.2.
[FIX] patch-bsd-df
space returned from statfs() is in number of blocks, which is not
necessarily 1024 bytes.
[FEATURE] patch-collapse-level
Extend collapse_destination_dir constraint to allow collapsing of up to an
arbitrary number of directory levels. This is useful if you have organized
files into sets by putting them into different source directories, such as
in the example below:
body copy_from copy_c1($srcdir) {
source => "$(srcdir");
collapse_destination_dir => 1;
}
bundle agent docopy($src, $dst) {
vars:
"dirs" slist => { "$(src)/$(sys.os)",
"$(src)/$(sys.os)-$(sys.arch)",
"$(src)/$(sys.os)-$(sys.release)",
"$(src)/$(sys.os)-$(sys.release)-$(sys.arch)",
"$(src)/.*/.*" };
files:
"$dst"
copy_from => copy_c1("$(src)"),
depth_search => recurse_pkg_includedirs("inf", "@(dirs)");
}
[FEATURE] patch-diskfree
adds diskfree(dir) function to return space available at any location.
[FEATURE] patch-dz-arithmetic
adds simple arithmetic functions
[FIX] patch-exclude-first
Fixes the bug where only include_dirs is considered when both include_dirs
and exclude_dirs are specified in a search, by evaluating the exclusion
list first.
[FIX] patch-linkstatus
Fixes the problem where various link promises are always counted as
repaired.
[FIX] patch-method-nochg
Fixes the problem where usemethod invocations are counted as extra repaired
promises.
[FIX] patch-moveobstructions-whennofile
Whether or not a directory is moved aside in file operations should not
depend on the when_no_source attribute.
[FEATURE/FIX] patch-netgroup
Allow various server controls to match based on netgroup in addition to IP
or hostname. Specify "@netgroup-name" in place of hostnames to do netgroup
matching.
This patch also fixes the lack of hostname based matching on the
trustkeysfrom and dynamicaddresses promises.
[FIX] patch-nodeleteslash
When verifying soft links, do not attempt to delete the trailing slash from
the current on-disk state if the expected link destination also has a
trailing slash.
[FIX] patch-nodupclass
Avoid adding duplicate result classes to the global class list. This
prevents /var/cfengine/state/allclasses.txt from exploding in size when you
have lots of result classes.
[FIX] patch-regex-detect
Improve regex detection in IsRegex() to decrease the chance of false
positives.
[FIX] patch-single-copy
The files_single_copy list was only being matched quazi-literally, where
the file name was actually being used as a regex and the single copy list
was being matched against that.
--- src/storage_tools.c~ 2009-08-24 21:37:25.000000000 -0400
+++ src/storage_tools.c 2009-08-24 21:38:53.000000000 -0400
@@ -100,9 +100,9 @@
#endif
#if defined NETBSD || defined FREEBSD || defined OPENBSD || defined SUNOS ||
defined HPuUX || defined DARWIN
- total = buf.f_blocks;
- used = buf.f_blocks - buf.f_bfree;
- avail = buf.f_bavail;
+ total = buf.f_blocks * buf.f_bsize / blocksize;
+ used = (buf.f_blocks - buf.f_bfree) * buf.f_bsize / blocksize;
+ avail = buf.f_bavail * buf.f_bsize / blocksize;
#endif
#if defined OSF
diff -u src~/attributes.c src/attributes.c
--- src~/attributes.c 2009-08-25 20:40:55.000000000 -0400
+++ src/attributes.c 2009-08-25 21:14:00.000000000 -0400
@@ -733,7 +733,13 @@
}
f.stealth = GetBooleanConstraint("stealth",pp->conlist);
-f.collapse = GetBooleanConstraint("collapse_destination_dir",pp->conlist);
+
+value = (char
*)GetConstraint("collapse_destination_dir",pp->conlist,CF_SCALAR);
+if (value == NULL)
+ f.collapse = 0;
+else
+ f.collapse = String2CollapseLevel(value);
+
f.preserve = GetBooleanConstraint("preserve",pp->conlist);
f.type_check = GetBooleanConstraint("type_check",pp->conlist);
f.force_update = GetBooleanConstraint("force_update",pp->conlist);
diff -u src~/conversion.c src/conversion.c
--- src~/conversion.c 2009-08-25 20:40:55.000000000 -0400
+++ src/conversion.c 2009-08-25 21:20:42.000000000 -0400
@@ -237,6 +237,29 @@
/****************************************************************************/
+int String2CollapseLevel(char *s)
+
+{ int i;
+ static char *infs[] = {"true", "yes", "on", "inf", NULL};
+ static char *zeros[] = {"false", "no", "off", NULL};
+
+if (!s) return 0;
+for (i = 0; infs[i] != NULL; i++)
+ {
+ if (strcmp(s,infs[i]) == 0)
+ return CF_INFINITY;
+ }
+for (i = 0; zeros[i] != NULL; i++)
+ {
+ if (strcmp(s,zeros[i]) == 0)
+ return 0;
+ }
+
+return (int)Str2Int(s);
+}
+
+/****************************************************************************/
+
enum cfcomparison String2Comparison(char *s)
{ int i;
diff -u src~/files_copy.c src/files_copy.c
--- src~/files_copy.c 2009-08-25 20:40:55.000000000 -0400
+++ src/files_copy.c 2009-08-25 20:59:45.000000000 -0400
@@ -80,7 +80,7 @@
CfOut(cf_verbose,""," ->> Entering %s\n",source);
SetSearchDevice(&ssb,pp);
- SourceSearchAndCopy(source,destination,attr.recursion.depth,attr,pp);
+ SourceSearchAndCopy(source,destination,attr.recursion.depth,0,attr,pp);
if (stat(destination,&dsb) != -1)
{
diff -u src~/files_interfaces.c src/files_interfaces.c
--- src~/files_interfaces.c 2009-08-25 20:40:55.000000000 -0400
+++ src/files_interfaces.c 2009-08-25 21:07:30.000000000 -0400
@@ -36,7 +36,7 @@
/* File copying is a special case, particularly complex - cannot be integrated
*/
-void SourceSearchAndCopy(char *from,char *to,int maxrecurse,struct Attributes
attr,struct Promise *pp)
+void SourceSearchAndCopy(char *from,char *to,int maxrecurse,int level,struct
Attributes attr,struct Promise *pp)
{ struct stat sb, dsb;
char newfrom[CF_BUFSIZE];
@@ -124,7 +124,7 @@
/* If we are tracking subdirs in copy, then join else don't add*/
- if (attr.copy.collapse)
+ if (level < attr.copy.collapse)
{
if (!S_ISDIR(sb.st_mode) && !JoinPath(newto,dirp->d_name))
{
@@ -164,7 +164,7 @@
/* Only copy dirs if we are tracking subdirs */
- if (!attr.copy.collapse && (stat(newto,&dsb) == -1))
+ if (!(level < attr.copy.collapse) && (stat(newto,&dsb) == -1))
{
if (mkdir(newto,0700) == -1)
{
@@ -181,12 +181,12 @@
CfOut(cf_verbose,""," ->> Entering %s\n",newto);
- if (!attr.copy.collapse)
+ if (!(level < attr.copy.collapse))
{
VerifyCopiedFileAttributes(newto,&dsb,&sb,attr,pp);
}
- SourceSearchAndCopy(newfrom,newto,maxrecurse-1,attr,pp);
+ SourceSearchAndCopy(newfrom,newto,maxrecurse-1,level+1,attr,pp);
}
else
{
diff -u src~/mod_files.c src/mod_files.c
--- src~/mod_files.c 2009-08-25 20:40:55.000000000 -0400
+++ src/mod_files.c 2009-08-25 21:11:16.000000000 -0400
@@ -303,7 +303,7 @@
{
{"source",cf_str,CF_PATHRANGE,"Reference source file from which to copy"},
{"servers",cf_slist,"[A-Za-z0-9_.:-]+","List of servers in order of
preference from which to copy"},
- {"collapse_destination_dir",cf_opts,CF_BOOL,"true/false Place files in
subdirectories into the root destination directory during copy"},
+
{"collapse_destination_dir",cf_str,"0|true|false|yes|no|on|off|[0-9][0-9]*|inf","Place
files in subdirectories into the root destination directory during copy, up to
the specified number of levels"},
{"compare",cf_opts,"atime,mtime,ctime,digest,hash","Menu option policy for
comparing source and image file attributes"},
{"copy_backup",cf_opts,"true,false,timestamp","Menu option policy for file
backup/version control"},
{"encrypt",cf_opts,CF_BOOL,"true/false use encrypted data stream to connect
to remote host"},
diff -u src~/prototypes3.h src/prototypes3.h
--- src~/prototypes3.h 2009-08-25 20:40:55.000000000 -0400
+++ src/prototypes3.h 2009-08-25 21:20:55.000000000 -0400
@@ -231,6 +231,7 @@
int Signal2Int(char *s);
enum cfreport String2ReportLevel(char *typestr);
enum cfhashes String2HashType(char *typestr);
+int String2CollapseLevel(char *s);
enum cfcomparison String2Comparison(char *s);
enum cflinktype String2LinkType(char *s);
enum cfdatatype Typename2Datatype(char *name);
@@ -550,7 +551,7 @@
/* files_interfaces.c */
-void SourceSearchAndCopy(char *from,char *to,int maxrecurse,struct Attributes
attr,struct Promise *pp);
+void SourceSearchAndCopy(char *from,char *to,int maxrecurse,int level,struct
Attributes attr,struct Promise *pp);
void VerifyCopy(char *source,char *destination,struct Attributes attr,struct
Promise *pp);
void PurgeLocalFiles(struct Item *filelist,char *directory,struct Attributes
attr,struct Promise *pp);
void CopyFile(char *sourcefile,char *destfile,struct stat sourcestatbuf,struct
Attributes attr, struct Promise *pp);
Only in src~: .mod_common.c.swp
diff -u src~/cf3.defs.h src/cf3.defs.h
--- src~/cf3.defs.h 2009-08-24 21:12:52.000000000 -0400
+++ src/cf3.defs.h 2009-08-24 21:13:55.000000000 -0400
@@ -488,6 +488,7 @@
cfn_changedbefore,
cfn_classify,
cfn_classmatch,
+ cfn_diskfree,
cfn_execresult,
cfn_fileexists,
cfn_filesexist,
diff -u src~/evalfunction.c src/evalfunction.c
--- src~/evalfunction.c 2009-08-24 21:12:52.000000000 -0400
+++ src/evalfunction.c 2009-08-24 21:42:52.000000000 -0400
@@ -3898,6 +3898,45 @@
return rval;
}
+/*********************************************************************/
+
+struct Rval FnCallDiskFree(struct FnCall *fp,struct Rlist *finalargs)
+
+{ static char *argtemplate[] =
+ {
+ CF_ANYSTRING,
+ NULL
+ };
+ static enum cfdatatype argtypes[] =
+ {
+ cf_str,
+ cf_notype
+ };
+
+ struct Rlist *rp;
+ struct Rval rval;
+ char buffer[CF_BUFSIZE];
+ u_long df;
+
+buffer[0] = '\0';
+ArgTemplate(fp,argtemplate,argtypes,finalargs); /* Arg validation */
+
+df = GetDiskUsage((char *)finalargs->item, cfabs);
+if (df == CF_INFINITY) df = 0;
+snprintf(buffer,CF_BUFSIZE-1,"%d", df);
+
+if ((rval.item = strdup(buffer)) == NULL)
+ {
+ FatalError("Memory allocation in FnCallGetGid");
+ }
+
+/* end fn specific content */
+
+rval.rtype = CF_SCALAR;
+return rval;
+}
+
+
/*********************************************************************/
/* Level */
diff -u src~/fncall.c src/fncall.c
--- src~/fncall.c 2009-08-24 21:12:52.000000000 -0400
+++ src/fncall.c 2009-08-24 21:16:16.000000000 -0400
@@ -444,6 +444,9 @@
case cfn_selectservers:
rval = FnCallSelectServers(fp,expargs);
break;
+ case cfn_diskfree:
+ rval = FnCallDiskFree(fp,expargs);
+ break;
case cfn_unknown:
CfOut(cf_error,"","Un-registered function call");
diff -u src~/mod_common.c src/mod_common.c
--- src~/mod_common.c 2009-08-24 21:12:52.000000000 -0400
+++ src/mod_common.c 2009-08-24 21:13:47.000000000 -0400
@@ -52,6 +52,7 @@
{"changedbefore",cf_class,2,"True if arg1 was changed before arg2 (ctime)"},
{"classify",cf_class,1,"True if the canonicalization of the argument is a
currently defined class"},
{"classmatch",cf_class,1,"True if the regular expression matches any
currently defined class"},
+ {"diskfree",cf_int,1,"Return the free space (in KB) available for a
directory (0 if not found)"},
{"execresult",cf_str,2,"Execute named command and assign output to
variable"},
{"fileexists",cf_class,1,"True if the named file can be accessed"},
{"filesexist",cf_class,1,"True if the named list of files can ALL be
accessed"},
diff -u src~/prototypes3.h src/prototypes3.h
--- src~/prototypes3.h 2009-08-24 21:12:52.000000000 -0400
+++ src/prototypes3.h 2009-08-24 21:16:06.000000000 -0400
@@ -437,6 +437,7 @@
struct Rval FnCallRegistryValue(struct FnCall *fp,struct Rlist *finalargs);
struct Rval FnCallLastNode(struct FnCall *fp,struct Rlist *finalargs);
struct Rval FnCallFileSexist(struct FnCall *fp,struct Rlist *finalargs);
+struct Rval FnCallDiskFree(struct FnCall *fp,struct Rlist *finalargs);
void *CfReadFile(char *filename,int maxsize);
char *StripPatterns(char *file_buffer,char *pattern);
diff -ur src~/cf3.defs.h src/cf3.defs.h
--- src~/cf3.defs.h 2009-08-24 22:04:43.000000000 -0400
+++ src/cf3.defs.h 2009-08-24 22:06:51.000000000 -0400
@@ -483,12 +483,14 @@
{
cfn_accessedbefore,
cfn_accum,
+ cfn_add,
cfn_ago,
cfn_canonify,
cfn_changedbefore,
cfn_classify,
cfn_classmatch,
cfn_diskfree,
+ cfn_divide,
cfn_execresult,
cfn_fileexists,
cfn_filesexist,
@@ -513,6 +515,7 @@
cfn_ldaparray,
cfn_ldaplist,
cfn_ldapvalue,
+ cfn_multiply,
cfn_now,
cfn_date,
cfn_peers,
@@ -540,6 +543,7 @@
cfn_splayclass,
cfn_splitstring,
cfn_strcmp,
+ cfn_subtract,
cfn_usemodule,
cfn_userexists,
cfn_unknown,
diff -ur src~/fncall.c src/fncall.c
--- src~/fncall.c 2009-08-24 22:04:43.000000000 -0400
+++ src/fncall.c 2009-08-24 22:15:14.000000000 -0400
@@ -447,6 +447,18 @@
case cfn_diskfree:
rval = FnCallDiskFree(fp,expargs);
break;
+ case cfn_add:
+ rval = FnCallArithmetic(fp,expargs,'+');
+ break;
+ case cfn_subtract:
+ rval = FnCallArithmetic(fp,expargs,'-');
+ break;
+ case cfn_multiply:
+ rval = FnCallArithmetic(fp,expargs,'*');
+ break;
+ case cfn_divide:
+ rval = FnCallArithmetic(fp,expargs,'/');
+ break;
case cfn_unknown:
CfOut(cf_error,"","Un-registered function call");
diff -ur src~/mod_common.c src/mod_common.c
--- src~/mod_common.c 2009-08-24 22:04:43.000000000 -0400
+++ src/mod_common.c 2009-08-24 22:17:25.000000000 -0400
@@ -47,12 +47,14 @@
{
{"accessedbefore",cf_class,2,"True if arg1 was accessed before arg2
(atime)"},
{"accumulated",cf_int,6,"Convert an accumulated amount of time into a
system representation"},
+ {"add",cf_int,2,"Add two integers"},
{"ago",cf_int,6,"Convert a time relative to now to an integer system
representation"},
{"canonify",cf_str,1,"Convert an abitrary string into a legal class name"},
{"changedbefore",cf_class,2,"True if arg1 was changed before arg2 (ctime)"},
{"classify",cf_class,1,"True if the canonicalization of the argument is a
currently defined class"},
{"classmatch",cf_class,1,"True if the regular expression matches any
currently defined class"},
{"diskfree",cf_int,1,"Return the free space (in KB) available for a
directory (0 if not found)"},
+ {"divide",cf_int,2,"Divide two integers"},
{"execresult",cf_str,2,"Execute named command and assign output to
variable"},
{"fileexists",cf_class,1,"True if the named file can be accessed"},
{"filesexist",cf_class,1,"True if the named list of files can ALL be
accessed"},
@@ -77,6 +79,7 @@
{"ldaparray",cf_class,6,"Extract all values from an ldap record"},
{"ldaplist",cf_slist,6,"Extract all named values from multiple ldap
records"},
{"ldapvalue",cf_str,6,"Extract the first matching named value from ldap"},
+ {"multiply",cf_int,2,"Multiply two integers"},
{"now",cf_int,0,"Convert the current time into system representation"},
{"on",cf_int,6,"Convert an exact date/time to an integer system
representation"},
{"peers",cf_slist,3,"Get a list of peers (not including ourself) from the
partition to which we belong"},
@@ -104,6 +107,7 @@
{"splayclass",cf_class,2,"True if the first argument's time-slot has
arrived, according to a policy in arg2"},
{"splitstring",cf_slist,3,"Convert a string in arg1 into a list of max arg3
strings by splitting on a regular expression in arg2"},
{"strcmp",cf_class,2,"True if the two strings match exactly"},
+ {"subtract",cf_int,2,"Subtract two integers"},
{"usemodule",cf_class,2,"Execute cfengine module script and set class if
successful"},
{"userexists",cf_class,1,"True if user name or numerical id exists on this
host"},
{NULL,cf_notype,0,NULL}
--- src/prototypes3.h~ 2009-08-24 22:22:00.000000000 -0400
+++ src/prototypes3.h 2009-08-24 22:22:16.000000000 -0400
@@ -438,6 +438,7 @@
struct Rval FnCallLastNode(struct FnCall *fp,struct Rlist *finalargs);
struct Rval FnCallFileSexist(struct FnCall *fp,struct Rlist *finalargs);
struct Rval FnCallDiskFree(struct FnCall *fp,struct Rlist *finalargs);
+struct Rval FnCallArithmetic(struct FnCall *fp,struct Rlist *finalargs,char
ch);
void *CfReadFile(char *filename,int maxsize);
char *StripPatterns(char *file_buffer,char *pattern);
--- src/evalfunction.c~ 2009-08-24 22:25:31.000000000 -0400
+++ src/evalfunction.c 2009-08-24 22:25:55.000000000 -0400
@@ -3937,6 +3937,63 @@
return rval;
}
+/*********************************************************************/
+
+struct Rval FnCallArithmetic(struct FnCall *fp,struct Rlist *finalargs, char
ch)
+
+{ static char *argtemplate[] =
+ {
+ CF_ANYSTRING,
+ CF_ANYSTRING,
+ NULL
+ };
+ static enum cfdatatype argtypes[] =
+ {
+ cf_str,
+ cf_str,
+ cf_notype
+ };
+
+ struct Rlist *rp;
+ struct Rval rval;
+ char buffer[CF_BUFSIZE];
+ int a, b;
+
+buffer[0] = '\0';
+
+ArgTemplate(fp,argtemplate,argtypes,finalargs); /* Arg validation */
+
+a = Str2Int(finalargs->item);
+b = Str2Int(finalargs->next->item);
+
+switch (ch)
+ {
+ case '+':
+ a += b;
+ break;
+ case '-':
+ a -= b;
+ break;
+ case '*':
+ a *= b;
+ break;
+ case '/':
+ if (b==0) a = 0; else a /= b;
+ break;
+ }
+
+snprintf(buffer,CF_BUFSIZE-1,"%d", a);
+
+if ((rval.item = strdup(buffer)) == NULL)
+ {
+ FatalError("Memory allocation in FnCallGetGid");
+ }
+
+/* end fn specific content */
+
+rval.rtype = CF_SCALAR;
+return rval;
+}
/*********************************************************************/
diff -ur src~/recursion.c src/recursion.c
--- src~/recursion.c 2009-08-26 00:06:42.000000000 -0400
+++ src/recursion.c 2009-08-26 00:07:38.000000000 -0400
@@ -217,18 +217,18 @@
{
Debug("SkipDirLinks(%s,%s)\n",path,lastnode);
-if ((r.include_dirs != NULL) && !(MatchRlistItem(r.include_dirs,path) ||
MatchRlistItem(r.include_dirs,lastnode)))
- {
- CfOut(cf_verbose,"","Skipping matched non-included directory %s\n",path);
- return true;
- }
-
if (MatchRlistItem(r.exclude_dirs,path) ||
MatchRlistItem(r.exclude_dirs,lastnode))
{
CfOut(cf_verbose,"","Skipping matched excluded directory %s\n",path);
return true;
}
+if ((r.include_dirs != NULL) && !(MatchRlistItem(r.include_dirs,path) ||
MatchRlistItem(r.include_dirs,lastnode)))
+ {
+ CfOut(cf_verbose,"","Skipping matched non-included directory %s\n",path);
+ return true;
+ }
+
return false;
}
diff -ur src~/files_interfaces.c src/files_interfaces.c
--- src~/files_interfaces.c 2009-08-22 08:05:02.000000000 -0400
+++ src/files_interfaces.c 2009-08-24 20:05:20.000000000 -0400
@@ -1322,7 +1322,7 @@
void LinkCopy(char *sourcefile,char *destfile,struct stat *sb,struct
Attributes attr, struct Promise *pp)
{ char linkbuf[CF_BUFSIZE],*lastnode;
- int succeed = false;
+ int status = CF_UNKNOWN;
struct stat dsb;
/* Link the file to the source, instead of copying */
@@ -1370,20 +1370,20 @@
if (*linkbuf == '.')
{
- succeed = VerifyRelativeLink(destfile,linkbuf,attr,pp);
+ status = VerifyRelativeLink(destfile,linkbuf,attr,pp);
}
else
{
- succeed = VerifyLink(destfile,linkbuf,attr,pp);
+ status = VerifyLink(destfile,linkbuf,attr,pp);
}
break;
case cfa_relative:
- succeed = VerifyRelativeLink(destfile,linkbuf,attr,pp);
+ status = VerifyRelativeLink(destfile,linkbuf,attr,pp);
break;
case cfa_absolute:
- succeed = VerifyAbsoluteLink(destfile,linkbuf,attr,pp);
+ status = VerifyAbsoluteLink(destfile,linkbuf,attr,pp);
break;
default:
@@ -1391,7 +1391,7 @@
return;
}
-if (succeed)
+if (status == CF_CHG || status == CF_NOP)
{
if (lstat(destfile,&dsb) == -1)
{
@@ -1402,7 +1402,12 @@
VerifyCopiedFileAttributes(destfile,&dsb,sb,attr,pp);
}
- cfPS(cf_inform,CF_CHG,"",pp,attr," -> Created link %s", destfile);
+ if (status == CF_CHG)
+ cfPS(cf_inform,status,"",pp,attr," -> Created link %s", destfile);
+ else if (status == CF_NOP)
+ ; /*cfPS(cf_inform,status,"",pp,attr," -> Link %s as promised",
destfile);*/
+ else
+ cfPS(cf_inform,status,"",pp,attr," -> Unable to create link %s",
destfile);
}
}
diff -ur src~/files_links.c src/files_links.c
--- src~/files_links.c 2009-08-22 08:08:32.000000000 -0400
+++ src/files_links.c 2009-08-24 20:00:50.000000000 -0400
@@ -34,7 +34,7 @@
/*****************************************************************************/
-int VerifyLink(char *destination,char *source,struct Attributes attr,struct
Promise *pp)
+char VerifyLink(char *destination,char *source,struct Attributes attr,struct
Promise *pp)
{ char to[CF_BUFSIZE],linkbuf[CF_BUFSIZE],saved[CF_BUFSIZE],absto[CF_BUFSIZE];
int nofile = false;
@@ -84,13 +84,13 @@
if (nofile && (attr.link.when_no_file != cfa_force) && (attr.link.when_no_file
!= cfa_delete))
{
CfOut(cf_inform,"","Source %s for linking is absent",absto);
- return false;
+ return CF_WARN;
}
if (nofile && attr.link.when_no_file == cfa_delete)
{
KillGhostLink(destination,attr,pp);
- return true;
+ return CF_CHG;
}
memset(linkbuf,0,CF_BUFSIZE);
@@ -99,16 +99,16 @@
{
if (!MakeParentDirectory(destination,attr.move_obstructions))
/* link doesn't exist */
{
- return true;
+ return CF_FAIL;
}
else
{
if (!MoveObstruction(destination,attr,pp))
{
- return false;
+ return CF_FAIL;
}
- return MakeLink(destination,to,attr,pp);
+ return MakeLink(destination,to,attr,pp)?CF_CHG:CF_FAIL;
}
}
else
@@ -137,34 +137,34 @@
if (unlink(destination) == -1)
{
perror("unlink");
- return true;
+ return CF_FAIL;
}
- return MakeLink(destination,to,attr,pp);
+ return MakeLink(destination,to,attr,pp)?CF_CHG:CF_FAIL;
}
else
{
CfOut(cf_error,""," !! Must remove incorrect link
%s\n",destination);
- return false;
+ return CF_FAIL;
}
}
else
{
cfPS(cf_inform,CF_FAIL,"",pp,attr," !! Link %s points to %s not %s -
not authorized to override",destination,linkbuf,to);
- return true;
+ return CF_FAIL;
}
}
else
{
cfPS(cf_inform,CF_NOP,"",pp,attr," -> Link %s points to %s - promise
kept",destination,to);
- return true;
+ return CF_NOP;
}
}
}
/*****************************************************************************/
-int VerifyAbsoluteLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp)
+char VerifyAbsoluteLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp)
{ char absto[CF_BUFSIZE];
char expand[CF_BUFSIZE];
@@ -194,7 +194,7 @@
{
CfOut(cf_error,""," !! Failed to make absolute link in\n");
PromiseRef(cf_error,pp);
- return false;
+ return CF_FAIL;
}
else
{
@@ -213,7 +213,7 @@
/*****************************************************************************/
-int VerifyRelativeLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp)
+char VerifyRelativeLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp)
{ char *sp, *commonto, *commonfrom;
char buff[CF_BUFSIZE],linkto[CF_BUFSIZE],add[CF_BUFSIZE];
@@ -229,7 +229,7 @@
if (!CompressPath(linkto,source))
{
cfPS(cf_error,CF_INTERPT,"",pp,attr," !! Failed to link %s to
%s\n",destination,source);
- return false;
+ return CF_FAIL;
}
commonto = linkto;
@@ -239,7 +239,7 @@
{
CfOut(cf_error,""," !! Can't link file %s to itself!\n",commonto);
PromiseRef(cf_error,pp);
- return false;
+ return CF_FAIL;
}
while (*commonto == *commonfrom)
@@ -275,13 +275,13 @@
if (!JoinPath(buff,add))
{
- return false;
+ return CF_FAIL;
}
}
if (!JoinPath(buff,commonto))
{
- return false;
+ return CF_FAIL;
}
return VerifyLink(destination,buff,attr,pp);
@@ -289,7 +289,7 @@
/*****************************************************************************/
-int VerifyHardLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp)
+char VerifyHardLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp)
{ char to[CF_BUFSIZE],linkbuf[CF_BUFSIZE],saved[CF_BUFSIZE],absto[CF_BUFSIZE];
struct stat ssb,dsb;
@@ -319,21 +319,20 @@
if (stat(absto,&ssb) == -1)
{
cfPS(cf_inform,CF_INTERPT,"",pp,attr," !! Source file %s doesn't
exist\n",source);
- return false;
+ return CF_WARN;
}
if (!S_ISREG(ssb.st_mode))
{
cfPS(cf_inform,CF_FAIL,"",pp,attr," !! Source file %s is not a regular
file, not appropriate to hard-link\n",to);
- return false;
+ return CF_WARN;
}
Debug2("Trying to (hard) link %s -> %s\n",destination,to);
if (stat(destination,&dsb) == -1)
{
- MakeHardLink(destination,to,attr,pp);
- return true;
+ return MakeHardLink(destination,to,attr,pp)?CF_CHG:CF_FAIL;
}
/* both files exist, but are they the same file? POSIX says */
@@ -348,25 +347,24 @@
if (dsb.st_mode == ssb.st_mode && dsb.st_size == ssb.st_size)
{
cfPS(cf_verbose,CF_NOP,"",pp,attr,"Hard link (%s->%s) on different
device APPEARS okay\n",destination,to);
- return true;
+ return CF_NOP;
}
}
if (dsb.st_ino == ssb.st_ino && dsb.st_dev == ssb.st_dev)
{
cfPS(cf_verbose,CF_NOP,"",pp,attr," -> Hard link (%s->%s) exists and is
okay\n",destination,to);
- return true;
+ return CF_NOP;
}
CfOut(cf_inform,""," !! %s does not appear to be a hard link to
%s\n",destination,to);
if (!MoveObstruction(destination,attr,pp))
{
- return false;
+ return CF_FAIL;
}
-MakeHardLink(destination,to,attr,pp);
-return true;
+return MakeHardLink(destination,to,attr,pp)?CF_CHG:CF_FAIL;
}
/*****************************************************************************/
diff -ur src~/prototypes3.h src/prototypes3.h
--- src~/prototypes3.h 2009-08-18 07:51:50.000000000 -0400
+++ src/prototypes3.h 2009-08-24 20:01:10.000000000 -0400
@@ -511,10 +511,10 @@
/* files_links.c */
-int VerifyLink(char *destination,char *source,struct Attributes attr,struct
Promise *pp);
-int VerifyAbsoluteLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp);
-int VerifyRelativeLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp);
-int VerifyHardLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp);
+char VerifyLink(char *destination,char *source,struct Attributes attr,struct
Promise *pp);
+char VerifyAbsoluteLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp);
+char VerifyRelativeLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp);
+char VerifyHardLink(char *destination,char *source,struct Attributes
attr,struct Promise *pp);
int KillGhostLink(char *name,struct Attributes attr,struct Promise *pp);
int MakeLink (char *from,char *to,struct Attributes attr,struct Promise *pp);
int MakeHardLink (char *from,char *to,struct Attributes attr,struct Promise
*pp);
--- src/verify_methods.c~ 2009-08-24 23:30:38.000000000 -0400
+++ src/verify_methods.c 2009-08-24 23:30:50.000000000 -0400
@@ -105,7 +105,7 @@
if (retval)
{
- cfPS(cf_verbose,CF_CHG,"",pp,a,"Method invoked successfully\n");
+ cfPS(cf_verbose,CF_REGULAR,"",pp,a,"Method invoked successfully\n");
}
else
{
--- src/logging.c~ 2009-08-24 23:34:09.000000000 -0400
+++ src/logging.c 2009-08-24 23:34:56.000000000 -0400
@@ -173,7 +173,6 @@
case CF_REGULAR:
AddAllClasses(attr.classes.change,attr.classes.persist,attr.classes.timer);
NotePromiseCompliance(pp,0.5);
- PR_REPAIRED++;
break;
case CF_UNKNOWN:
--- src/files_operators.c~ 2009-08-26 13:34:17.000000000 -0400
+++ src/files_operators.c 2009-08-26 13:34:29.000000000 -0400
@@ -739,7 +739,7 @@
return true;
}
- if (S_ISDIR(sb.st_mode) && attr.link.when_no_file == cfa_force)
+ if (S_ISDIR(sb.st_mode))
{
cfPS(cf_verbose,CF_CHG,"",pp,attr," -> Moving directory %s to
%s%s\n",from,from,CF_SAVED);
diff -ur src.orig/item-lib.c src/item-lib.c
--- src.orig/item-lib.c 2009-08-31 16:44:08.000000000 +0000
+++ src/item-lib.c 2009-08-31 17:01:53.000000000 +0000
@@ -910,6 +910,47 @@
return(false);
}
+int IsHostIn(struct Item *list,char *ip,char*username,char*hostname)
+
+/* Solve for possible regex/fuzzy models unified */
+
+{ struct Item *ptr;
+
+if ((ip == NULL) || (strlen(ip) == 0))
+ {
+ return true;
+ }
+
+for (ptr = list; ptr != NULL; ptr=ptr->next)
+ {
+ if (ptr->name[0] == '@' && hostname)
+ {
+ if (innetgr(ptr->name+1, hostname, username?username:"", NULL))
+ return(true);
+ }
+
+ if (FuzzySetMatch(ptr->name,ip) == 0)
+ {
+ return(true);
+ }
+
+ if (IsRegex(ptr->name))
+ {
+ if (FullTextMatch(ptr->name,ip))
+ {
+ return(true);
+ }
+
+ if (hostname && FullTextMatch(ptr->name,hostname))
+ {
+ return(true);
+ }
+ }
+ }
+
+return(false);
+}
+
/*********************************************************************/
int IsFuzzyItemIn(struct Item *list,char *item)
Only in src: item-lib.c~
diff -ur src.orig/prototypes3.h src/prototypes3.h
--- src.orig/prototypes3.h 2009-08-31 16:44:08.000000000 +0000
+++ src/prototypes3.h 2009-08-31 16:58:45.000000000 +0000
@@ -774,6 +774,7 @@
int IsItemIn (struct Item *list, char *item);
int IsFuzzyItemIn (struct Item *list, char *item);
int IsMatchItemIn(struct Item *list,char *item);
+int IsHostIn(struct Item *list,char *ip,char *username,char *hostname);
int GetItemListCounter (struct Item *list, char *item);
struct Item *ConcatLists (struct Item *list1, struct Item *list2);
void CopyList (struct Item **dest,struct Item *source);
Only in src: prototypes3.h~
diff -ur src.orig/server.c src/server.c
--- src.orig/server.c 2009-08-31 16:44:08.000000000 +0000
+++ src/server.c 2009-08-31 17:08:29.000000000 +0000
@@ -1950,7 +1950,7 @@
{
Debug("Checking whether to map root privileges..\n");
- if (IsMatchItemIn(ap->maproot,MapAddress(conn->ipaddr)) ||
IsRegexItemIn(ap->maproot,conn->hostname))
+ if
(IsHostIn(ap->maproot,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
conn->maproot = true;
CfOut(cf_verbose,"","Mapping root privileges\n");
@@ -1960,7 +1960,7 @@
CfOut(cf_verbose,"","No root privileges granted\n");
}
- if (IsMatchItemIn(ap->accesslist,MapAddress(conn->ipaddr)) ||
IsRegexItemIn(ap->accesslist,conn->hostname))
+ if
(IsHostIn(ap->accesslist,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
access = true;
Debug("Access privileges - match found\n");
@@ -1974,8 +1974,7 @@
{
if (strncmp(transpath,transrequest,strlen(transpath)) == 0)
{
- if (IsMatchItemIn(ap->accesslist,MapAddress(conn->ipaddr)) ||
- IsRegexItemIn(ap->accesslist,conn->hostname))
+ if
(IsHostIn(ap->accesslist,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
access = false;
CfOut(cf_verbose,"","Host %s explicitly denied access to
%s\n",conn->hostname,transrequest);
@@ -2048,7 +2047,7 @@
{
Debug("Checking whether to map root privileges..\n");
- if (IsMatchItemIn(ap->maproot,MapAddress(conn->ipaddr)) ||
IsRegexItemIn(ap->maproot,conn->hostname))
+ if
(IsHostIn(ap->maproot,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
conn->maproot = true;
CfOut(cf_verbose,"","Mapping root privileges\n");
@@ -2058,7 +2057,7 @@
CfOut(cf_verbose,"","No root privileges granted\n");
}
- if (IsMatchItemIn(ap->accesslist,MapAddress(conn->ipaddr)) ||
IsRegexItemIn(ap->accesslist,conn->hostname))
+ if
(IsHostIn(ap->accesslist,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
access = true;
Debug("Access privileges - match found\n");
@@ -2072,7 +2071,7 @@
{
if (strcmp(ap->path,name) == 0)
{
- if (IsMatchItemIn(ap->accesslist,MapAddress(conn->ipaddr)) ||
IsRegexItemIn(ap->accesslist,conn->hostname))
+ if
(IsHostIn(ap->accesslist,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
access = false;
CfOut(cf_verbose,"","Host %s explicitly denied access to
%s\n",conn->hostname,name);
@@ -2148,8 +2147,7 @@
if (FullTextMatch(ap->path,rp->item))
{
/* We have a pattern covering this class - so are we allowed to
activate it? */
- if (IsMatchItemIn(ap->accesslist,MapAddress(conn->ipaddr)) ||
- IsRegexItemIn(ap->accesslist,conn->hostname) ||
+ if
(IsHostIn(ap->accesslist,MapAddress(conn->ipaddr),conn->username,conn->hostname)
||
IsRegexItemIn(ap->accesslist,userid1) ||
IsRegexItemIn(ap->accesslist,userid2) ||
IsRegexItemIn(ap->accesslist,conn->username)
@@ -3279,7 +3277,7 @@
{
/* If we find a key, but it doesn't match, see if we permit dynamical IP
addressing */
- if ((DHCPLIST != NULL) &&
IsMatchItemIn(DHCPLIST,MapAddress(conn->ipaddr)))
+ if ((DHCPLIST != NULL) &&
IsHostIn(DHCPLIST,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
int result;
result =
IsKnownHost(savedkey,key,MapAddress(conn->ipaddr),conn->username);
@@ -3305,11 +3303,11 @@
return true;
}
-else if ((DHCPLIST != NULL) &&
IsMatchItemIn(DHCPLIST,MapAddress(conn->ipaddr)))
+else if ((DHCPLIST != NULL) &&
IsHostIn(DHCPLIST,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
/* If the host is expected to have a dynamic address, check for the key */
- if ((DHCPLIST != NULL) && IsMatchItemIn(DHCPLIST,MapAddress(conn->ipaddr)))
+ if ((DHCPLIST != NULL) &&
IsHostIn(DHCPLIST,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
int result;
result =
IsKnownHost(savedkey,key,MapAddress(conn->ipaddr),conn->username);
@@ -3328,7 +3326,7 @@
/* Finally, if we're still here, we should consider trusting a new key ... */
-if ((TRUSTKEYLIST != NULL) &&
IsMatchItemIn(TRUSTKEYLIST,MapAddress(conn->ipaddr)))
+if ((TRUSTKEYLIST != NULL) &&
IsHostIn(TRUSTKEYLIST,MapAddress(conn->ipaddr),conn->username,conn->hostname))
{
CfOut(cf_verbose,"","Host %s/%s was found in the list of hosts to
trust\n",conn->hostname,conn->ipaddr);
conn->trust = true;
--- src/files_links.c~ 2009-09-02 21:19:52.000000000 -0400
+++ src/files_links.c 2009-09-02 21:21:13.000000000 -0400
@@ -114,7 +114,8 @@
else
{ int off1 = 0, off2 = 0; /* Link exists */
- DeleteSlash(linkbuf);
+ if (*to && !IsFileSep(to[strlen(to)-1]))
+ DeleteSlash(linkbuf);
if (strncmp(linkbuf,"./",2) == 0) /* Ignore ./ at beginning */
{
--- src/logging.c~ 2009-08-27 20:48:10.000000000 -0400
+++ src/logging.c 2009-08-27 20:48:16.000000000 -0400
@@ -274,12 +274,14 @@
{
CfOut(cf_verbose,""," ?> defining persistent promise result class
%s\n",(char *)rp->item);
NewPersistentContext(rp->item,persist,policy);
- PrependItem(&VHEAP,CanonifyName((char *)rp->item),NULL);
+ if (!IsItemIn(VHEAP, CanonifyName((char *)rp->item)))
+ PrependItem(&VHEAP,CanonifyName((char *)rp->item),NULL);
}
else
{
CfOut(cf_verbose,""," ?> defining promise result class %s\n",(char
*)rp->item);
- PrependItem(&VHEAP,CanonifyName((char *)rp->item),NULL);
+ if (!IsItemIn(VHEAP, CanonifyName((char *)rp->item)))
+ PrependItem(&VHEAP,CanonifyName((char *)rp->item),NULL);
}
}
}
--- src/matching.c~ 2009-08-27 12:45:55.000000000 -0400
+++ src/matching.c 2009-08-27 13:23:59.000000000 -0400
@@ -158,16 +158,71 @@
int IsRegex(char *str)
{ char *sp;
+ int ret = false;
+ enum { r_norm, r_norepeat, r_literal } special = r_norepeat;
+ int bracket = 0;
+ int paren = 0;
for (sp = str; *sp != '\0'; sp++)
{
- if (strchr("^*+\[]()$",*sp))
+ if (special == r_literal)
{
- return true; /* Maybe */
+ special = r_norm;
+ continue;
+ }
+ else if (*sp == '\\')
+ {
+ special = r_literal;
+ continue;
+ }
+ else if (bracket && *sp != ']')
+ {
+ if (*sp == '[') return false;
+ continue;
+ }
+
+ switch (*sp)
+ {
+ case '^':
+ special = (sp == str)?r_norepeat:r_norm;
+ break;
+ case '*':
+ case '+':
+ if (special == r_norepeat) return false;
+ special = r_norepeat;
+ ret = true;
+ break;
+ case '[':
+ special = r_norm;
+ bracket++;
+ ret = true;
+ break;
+ case ']':
+ if (bracket == 0) return false;
+ bracket = 0;
+ special = r_norm;
+ break;
+ case '(':
+ special = r_norepeat;
+ paren++;
+ break;
+ case ')':
+ special = r_norm;
+ paren--;
+ if (paren < 0) return false;
+ break;
+ case '|':
+ special = r_norepeat;
+ if (paren > 0) ret = true;
+ break;
+ default:
+ special = r_norm;
}
+
}
-return false;
+if (bracket != 0 || paren != 0 || special == r_literal) return false;
+return ret;
}
/*********************************************************************/
--- src/files_interfaces.c~ 2009-09-02 17:24:07.000000000 -0400
+++ src/files_interfaces.c 2009-09-02 17:25:06.000000000 -0400
@@ -647,7 +647,7 @@
return;
}
-if (IsStringIn(SINGLE_COPY_CACHE,destfile))
+if (IsInListOfRegex(SINGLE_COPY_CACHE,destfile))
{
CfOut(cf_inform,""," -> Skipping single-copied file %s\n",destfile);
return;
@@ -898,7 +898,7 @@
VerifyCopiedFileAttributes(destfile,&dsb,&ssb,attr,pp);
}
- if (IsRegexIn(SINGLE_COPY_LIST,destfile))
+ if (IsInListOfRegex(SINGLE_COPY_LIST,destfile))
{
IdempPrependRScalar(&SINGLE_COPY_CACHE,destfile,CF_SCALAR);
}
@@ -924,7 +924,7 @@
otherwise we can get oscillations between multipe versions if type
is based on a checksum */
- if (IsRegexIn(SINGLE_COPY_LIST,destfile))
+ if (IsInListOfRegex(SINGLE_COPY_LIST,destfile))
{
IdempPrependRScalar(&SINGLE_COPY_CACHE,destfile,CF_SCALAR);
}
_______________________________________________
Bug-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/bug-cfengine