/* cfengine for GNU Copyright (C) 1995 Free Software Foundation, Inc. This file is part of GNU cfengine - written and maintained by Mark Burgess, Dept of Computing and Engineering, Oslo College, Dept. of Theoretical physics, University of Oslo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /*********************************************************************/ /* */ /* TOOLKIT: the "item file extension" object for cfengine */ /* */ /*********************************************************************/ #include "cf.defs.h" #include "cf.extern.h" /*********************************************************************/ int LoadItemList(liststart,file) struct Item **liststart; char *file; { FILE *fp; struct stat statbuf; if (stat(file,&statbuf) == -1) { sprintf(OUTPUT,"Couldn't stat %s\n",file); CfLog(cfverbose,OUTPUT,"stat"); return false; } if ((EDITFILESIZE != 0) &&(statbuf.st_size > EDITFILESIZE)) { sprintf(OUTPUT,"File %s is bigger than the limit \n",file); CfLog(cfinform,OUTPUT,""); return(false); } if (! S_ISREG(statbuf.st_mode)) { sprintf(OUTPUT,"%s is not a plain file\n",file); CfLog(cfinform,OUTPUT,""); return false; } if ((fp = fopen(file,"r")) == NULL) { sprintf(OUTPUT,"Couldn't read file %s for editing\n",file); CfLog(cferror,OUTPUT,"fopen"); return false; } bzero(VBUFF,bufsize); while(!feof(fp)) { ReadLine(VBUFF,bufsize,fp); if (!feof(fp) || (strlen(VBUFF) != 0)) { AppendItem(liststart,VBUFF,NULL); } VBUFF[0] = '\0'; } fclose(fp); return (true); } /*********************************************************************/ int SaveItemList(liststart,file,repository) struct Item *liststart; char *file, *repository; { struct Item *ip; struct stat statbuf; char new[bufsize],backup[bufsize]; FILE *fp; mode_t mask; if (stat(file,&statbuf) == -1) { sprintf(OUTPUT,"Couldn't stat %s, which needed editing!\n",file); CfLog(cferror,OUTPUT,""); CfLog(cferror,"Check definition in program - is file NFS mounted?\n\n",""); return false; } strcpy(new,file); strcat(new,CF_EDITED); strcpy(backup,file); strcat(backup,CF_SAVED); unlink(new); /* Just in case of races */ if ((fp = fopen(new,"w")) == NULL) { sprintf(OUTPUT,"Couldn't write file %s after editing\n",new); CfLog(cferror,OUTPUT,""); return false; } for (ip = liststart; ip != NULL; ip=ip->next) { fprintf(fp,"%s\n",ip->name); } sprintf(OUTPUT,"Edited file %s \n",file); CfLog(cfinform,OUTPUT,""); fclose(fp); if (! IsItemIn(VREPOSLIST,new)) { if (rename(file,backup) == -1) { sprintf(OUTPUT,"Error while renaming backup %s\n",file); CfLog(cferror,OUTPUT,"rename "); unlink(new); return false; } else if (Repository(backup,repository)) { unlink(backup); } } if (rename(new,file) == -1) { sprintf(OUTPUT,"Error while renaming %s\n",file); CfLog(cferror,OUTPUT,"rename"); return false; } mask = umask(0); chmod(file,statbuf.st_mode); /* Restore file permissions etc */ chown(file,statbuf.st_uid,statbuf.st_gid); umask(mask); return true; } /*********************************************************************/ int CompareToFile(liststart,file) /* returns true if file on disk is identical to file in memory */ struct Item *liststart; char *file; { FILE *fp; struct stat statbuf; struct Item *ip = liststart; Debug("CompareToFile(%s)\n",file); if (stat(file,&statbuf) == -1) { return false; } if (liststart == NULL) { return false; } if ((fp = fopen(file,"r")) == NULL) { sprintf(OUTPUT,"Couldn't read file %s for editing\n",file); CfLog(cferror,OUTPUT,"fopen"); return false; } bzero(VBUFF,bufsize); for (ip = liststart; ip != NULL; ip=ip->next) { ReadLine(VBUFF,bufsize,fp); if (feof(fp) && (ip->next != NULL)) { fclose(fp); return false; } if ((ip->name == NULL) && (strlen(VBUFF) == 0)) { continue; } if (ip->name == NULL) { fclose(fp); return false; } if (strcmp(ip->name,VBUFF) != 0) { fclose(fp); return false; } VBUFF[0] = '\0'; } if (!feof(fp)) { fclose(fp); return false; } fclose(fp); return (true); }