Main Page | Class List | Directories | File List | Class Members | File Members

functions.c

Go to the documentation of this file.
00001 /* 
00002 
00003         Copyright (C) 1995-
00004         Free Software Foundation, Inc.
00005 
00006    This file is part of GNU cfengine - written and maintained 
00007    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
00008    Dept. of Theoretical physics, University of Oslo
00009  
00010    This program is free software; you can redistribute it and/or modify it
00011    under the terms of the GNU General Public License as published by the
00012    Free Software Foundation; either version 2, or (at your option) any
00013    later version.
00014  
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019  
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
00023 
00024 */
00025 
00026 /*****************************************************************************/
00027 /*                                                                           */
00028 /* File: functions.c                                                         */
00029 /*                                                                           */
00030 /*****************************************************************************/
00031 
00032 #include "cf.defs.h"
00033 #include "cf.extern.h"
00034 
00035 void GetRandom ARGLIST((char* args,char *value));
00036 void HandleFunctionExec ARGLIST((char* args,char *value));
00037 void HandleStatInfo ARGLIST((enum builtin fn,char* args,char *value));
00038 void HandleCompareStat ARGLIST((enum builtin fn,char* args,char *value));
00039 void HandleReturnsZero ARGLIST((char* args,char *value));
00040 void HandleIPRange ARGLIST((char* args,char *value));
00041 void HandleIsDefined ARGLIST((char* args,char *value));
00042 void HandleStrCmp ARGLIST((char* args,char *value));
00043 void HandleShowState ARGLIST((char* args,char *value));
00044 
00045 /*********************************************************************/
00046 
00047 int IsBuiltinFunction(item)
00048 
00049 char *item;
00050 
00051 { char name[maxvarsize],args[bufsize];
00052   char c1 = '?',c2 = '?' ;
00053 
00054 sscanf(item,"%255[a-zA-Z0-9_]%c%255[^)]%c",name,&c1,args,&c2);
00055 
00056 if (c1 != '(' || c2 != ')')
00057    {
00058    return false;
00059    }
00060  
00061 Debug("IsBuiltinFunction: %s(%s)\n",name,args);
00062 return true; 
00063 }
00064 
00065 /*********************************************************************/
00066 
00067 char *EvaluateFunction(f,value)
00068 
00069 char *f,*value;
00070 
00071 { enum builtin fn;
00072   char name[maxvarsize],vargs[bufsize],args[bufsize];
00073 
00074 sscanf(f,"%255[^(](%255[^)])",name,vargs);
00075 ExpandVarstring(vargs,args,NULL); 
00076 Debug("HandleFunction: %s(%s)\n",name,args);
00077 
00078 switch (fn = FunctionStringToCode(name))
00079    {
00080    case fn_randomint:
00081        GetRandom(args,value);
00082        break;
00083    case fn_newerthan:
00084    case fn_accessedbefore:
00085    case fn_changedbefore:
00086        HandleCompareStat(fn,args,value);
00087        break;
00088    case fn_fileexists:
00089    case fn_isdir:
00090    case fn_islink:
00091    case fn_isplain:
00092        HandleStatInfo(fn,args,value);
00093        break;
00094    case fn_execresult:
00095        HandleFunctionExec(args,value);
00096        break;
00097    case fn_returnszero:
00098        HandleReturnsZero(args,value);
00099        break;
00100    case fn_iprange:
00101        HandleIPRange(args,value);
00102        break;
00103    case fn_isdefined:
00104        HandleIsDefined(args,value);
00105        break;
00106    case fn_strcmp:
00107        HandleStrCmp(args,value);
00108        break;
00109    case fn_showstate:
00110        HandleShowState(args,value);
00111        break;
00112    }
00113  
00114 return value;
00115 }
00116 
00117 /*********************************************************************/
00118 /* level 1                                                           */
00119 /*********************************************************************/
00120 
00121 enum builtin FunctionStringToCode(str)
00122 
00123 char *str;
00124 
00125 { char *sp;
00126   int i;
00127   enum builtin fn;
00128 
00129 fn = nofn;
00130 
00131 for (sp = str; *sp != '\0'; sp++)
00132    {
00133    *sp = ToLower(*sp);
00134    if (*sp == ':')
00135       {
00136       *sp = '\0';
00137       }
00138    }
00139 
00140 for (i = 1; BUILTINS[i] != '\0'; i++)
00141    {
00142    if (strcmp(BUILTINS[i],str) == 0)
00143       {
00144       fn = (enum builtin) i;
00145       break;
00146       }
00147    }
00148 
00149 if (fn == nofn)
00150   {
00151   snprintf(OUTPUT,bufsize,"Internal function %s not recognized",str);
00152   yyerror(OUTPUT);
00153   FatalError("Could not parse function");
00154   }
00155 
00156 return (enum builtin) i;
00157 }
00158 
00159 /*********************************************************************/
00160 
00161 void GetRandom(args,value)
00162 
00163 char *args,*value;
00164 
00165 { int result,count=0,from=-1,to=-1;
00166   char *sp;
00167 
00168 if (ACTION != control)
00169    {
00170    yyerror("Use of RandInt(a,b) outside of variable assignment");
00171    }
00172   
00173 for (sp = args; *sp != '\0'; sp++)
00174    {
00175    if (*sp == ',')
00176       {
00177       count++;
00178       }
00179    }
00180 
00181 if (count != 1)
00182    {
00183    yyerror("RandomInt(a,b): argument error");
00184    return;
00185    }
00186  
00187 sscanf(args,"%d,%d",&from,&to);
00188 
00189 if ((from < 0) || (to < 0) || (from == to))
00190    {
00191    yyerror("RandomInt(a,b) must have different non-negative arguments < INT_MAX");
00192    return;
00193    }
00194 
00195 if (from > to)
00196    {
00197    yyerror("RandomInt(a,b) - b was less than a");
00198    return;
00199    }
00200 
00201 result = from + (int)(drand48()*(double)(to-from));
00202 Debug("RandomInt(%u)\n",result);
00203 snprintf(value,bufsize,"%u",result); 
00204 }
00205 
00206 /*********************************************************************/
00207 
00208 void HandleStatInfo(fn,args,value)
00209 
00210 enum builtin fn;
00211 char *args,*value;
00212 
00213 { struct stat statbuf;
00214 
00215 if (strchr(args,','))
00216    {
00217    yyerror("Illegal argument to unary class-function");
00218    return;
00219    }
00220 
00221 if (lstat(args,&statbuf) == -1)
00222    {
00223    strcpy(value,CF_NOCLASS);
00224    return;
00225    }
00226  else
00227     {
00228     if (fn == fn_fileexists)
00229        {
00230        strcpy(value,CF_ANYCLASS);
00231        return;
00232        }
00233     }
00234  
00235 strcpy(value,CF_NOCLASS);
00236 
00237  switch(fn)
00238     {
00239     case fn_isdir:
00240         if (S_ISDIR(statbuf.st_mode))
00241            {
00242            strcpy(value,CF_ANYCLASS);
00243            return;
00244            }
00245         break;
00246     case fn_islink:
00247         if (S_ISLNK(statbuf.st_mode))
00248            {
00249            strcpy(value,CF_ANYCLASS);
00250            return;
00251            }
00252         break;
00253     case fn_isplain:
00254         if (S_ISREG(statbuf.st_mode))
00255            {
00256            strcpy(value,CF_ANYCLASS);
00257            return;
00258            }
00259         break;
00260     }
00261  
00262 strcpy(value,CF_NOCLASS);
00263 }
00264 
00265 /*********************************************************************/
00266 
00267 void HandleIPRange(args,value)
00268 
00269 char *args,*value;
00270 
00271 { struct stat statbuf;
00272  
00273 if (strchr(args,','))
00274    {
00275    yyerror("Illegal argument to unary class-function");
00276    return;
00277    }
00278  
00279 strcpy(value,CF_NOCLASS);
00280 
00281 if (!FuzzyMatchParse(args))
00282    {
00283    return;
00284    }
00285 
00286 if (FuzzySetMatch(args,VIPADDRESS) == 0)
00287    {
00288    strcpy(value,CF_ANYCLASS);
00289    }
00290 }
00291 
00292 /*********************************************************************/
00293 
00294 void HandleCompareStat(fn,args,value)
00295 
00296 enum builtin fn;
00297 char *args,*value;
00298 
00299 { struct stat frombuf,tobuf;
00300   char *sp,from[bufsize],to[bufsize];
00301   int count = 0;
00302 
00303 from[0] = '\0';
00304 to[0] = '\0';
00305 
00306 for (sp = args; *sp != '\0'; sp++)
00307    {
00308    if (*sp == ',')
00309       {
00310       count++;
00311       }
00312    }
00313 
00314 if (count != 1)
00315    {
00316    yyerror("RandomInt(a,b): argument error");
00317    return;
00318    }
00319  
00320 sscanf(args,"%[^,],%[^)]",from,to);
00321 Debug("Comparing [%s] < [%s]\n",from,to);
00322  
00323 if (from[0]=='\0' || to[0] == '\0')
00324    {
00325    yyerror("Argument error in class-function");
00326    return;
00327    }
00328 
00329 strcpy(value,CF_NOCLASS);
00330  
00331 if (stat(from,&frombuf) == -1)
00332    {
00333    return;
00334    }
00335 
00336 if (stat(to,&tobuf) == -1)
00337    {
00338    return;
00339    }
00340 
00341 switch(fn)
00342    {
00343    case fn_newerthan:
00344        if (frombuf.st_mtime > tobuf.st_mtime)
00345           {
00346           strcpy(value,CF_ANYCLASS);
00347           return;
00348           }
00349        break;
00350 
00351    case fn_accessedbefore:
00352        if (frombuf.st_atime < tobuf.st_atime)
00353           {
00354           strcpy(value,CF_ANYCLASS);
00355           return;
00356           }
00357        break;
00358 
00359    case fn_changedbefore:
00360        if (frombuf.st_ctime < tobuf.st_ctime)
00361           {
00362           strcpy(value,CF_ANYCLASS);
00363           return;
00364           }       
00365        break;
00366    }
00367 
00368 strcpy(value,CF_NOCLASS);
00369 }
00370 
00371 
00372 /*********************************************************************/
00373 
00374 void HandleFunctionExec(args,value)
00375 
00376 char *args,*value;
00377 
00378 { char command[maxvarsize];
00379 
00380  if (ACTION != control)
00381    {
00382    yyerror("Use of ExecResult(s) outside of variable assignment");
00383    }
00384  
00385 if (*args == '/')
00386    {
00387    strncpy(command,args,maxvarsize);
00388    GetExecOutput(command,value);
00389    Chop(value);
00390    value[maxvarsize-1] = '\0';  /* Truncate to maxvarsize */
00391    }
00392  else
00393     {
00394     yyerror("ExecResult(/command) must specify an absolute path");
00395     } 
00396 }
00397 
00398 /*********************************************************************/
00399 
00400 void HandleReturnsZero(args,value)
00401 
00402 char *args,*value;
00403 
00404 { char command[bufsize];
00405 
00406 if (ACTION != groups)
00407    {
00408    yyerror("Use of ReturnsZero(s) outside of class assignment");
00409    }
00410 
00411 Debug("HandleReturnsZero(%s)\n",args); 
00412  
00413 if (*args == '/')
00414    {
00415    strncpy(command,args,bufsize);
00416    
00417    if (ShellCommandReturnsZero(command))
00418       {
00419       strcpy(value,CF_ANYCLASS);
00420       return;
00421       }
00422    }
00423  else
00424     {
00425     yyerror("ExecResult(/command) must specify an absolute path");
00426     }
00427 
00428 strcpy(value,CF_NOCLASS); 
00429 }
00430 
00431 
00432 /*********************************************************************/
00433 
00434 void HandleIsDefined(args,value)
00435 
00436 char *args,*value;
00437 
00438 {
00439 if (ACTION != groups)
00440    {
00441    yyerror("Use of IsDefined(s) outside of class assignment");
00442    }
00443 
00444 Debug("HandleIsDefined(%s)\n",args); 
00445  
00446 if (GetMacroValue(CONTEXTID,args))
00447    {
00448    strcpy(value,CF_ANYCLASS);
00449    return;
00450    }
00451 
00452 strcpy(value,CF_NOCLASS); 
00453 }
00454 
00455 
00456 /*********************************************************************/
00457 
00458 void HandleStrCmp(args,value)
00459 
00460 char *args,*value;
00461 
00462 { char *sp,from[bufsize],to[bufsize],*nfrom,*nto;
00463   int count = 0;
00464 
00465 from[0] = '\0';
00466 to[0] = '\0';
00467 
00468 for (sp = args; *sp != '\0'; sp++)
00469    {
00470    if (*sp == ',')
00471       {
00472       count++;
00473       }
00474    }
00475 
00476 if (count != 1)
00477    {
00478    yyerror("StrCmp(a,b): argument error");
00479    return;
00480    }
00481  
00482 sscanf(args,"%[^,],%[^)]",from,to);
00483 Debug("Comparing [%s] < [%s]\n",from,to);
00484  
00485 if (from[0]=='\0' || to[0] == '\0')
00486    {
00487    yyerror("Argument error in class-function");
00488    return;
00489    }
00490 
00491 nfrom = UnQuote(from);
00492 nto = UnQuote(to);
00493  
00494 if (strcmp(nfrom,nto) == 0)
00495    {
00496    strcpy(value,CF_ANYCLASS); 
00497    }
00498  else
00499     {
00500     strcpy(value,CF_NOCLASS);
00501     } 
00502 }
00503 
00504 
00505 
00506 /*********************************************************************/
00507 
00508 void HandleShowState(args,value)
00509 
00510 char *args,*value;
00511 
00512 { struct stat statbuf;
00513   char buffer[bufsize]; 
00514   FILE *fp;
00515   int i = 0;
00516   
00517 if (PARSING)
00518    {
00519    return;
00520    }
00521   
00522 if (ACTION != alerts)
00523    {
00524    yyerror("Use of ShowState(type) outside of alert declaration");
00525    }
00526 
00527 Debug("ShowState(%s)\n",args); 
00528 
00529 snprintf(buffer,bufsize,"%s/state/cf_%s",WORKDIR,args);
00530 
00531 if (stat(buffer,&statbuf) == 0)
00532    {
00533    if ((fp = fopen(buffer,"r")) == NULL)
00534       {
00535       Verbose("Could not open state %s\n",buffer);
00536       return;
00537       }
00538 
00539    while(!feof(fp))
00540       {
00541       buffer[0] = '\0';
00542       
00543       fgets(buffer,bufsize,fp);
00544       i++;
00545 
00546       if (strlen(buffer) > 0)
00547          {
00548          printf("%s: (%2d) %s",VPREFIX,i,buffer);
00549          }
00550       }
00551    
00552    fclose(fp);
00553    snprintf(buffer,bufsize,"State of %s recorded at %s\n",args,ctime(&statbuf.st_mtime));
00554    strcpy(value,buffer);
00555    }
00556 else 
00557    {
00558    snprintf(buffer,bufsize,"State parameter %s is not known or recorded\n",args);
00559    strcpy(value,buffer);
00560    }
00561 }
00562 

© sourcejam.com 2005-2008