files.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2002 by Contributors to the monit codebase. 
00003  * All Rights Reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <stdio.h>
00023 #include <errno.h>
00024 #include <stdlib.h>
00025 
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029 
00030 #ifdef HAVE_STRINGS_H
00031 #include <strings.h>
00032 #endif
00033 
00034 #ifdef HAVE_UNISTD_H
00035 #include <unistd.h>
00036 #endif
00037 
00038 #ifdef HAVE_SYS_TYPES_H
00039 #include <sys/types.h>
00040 #endif
00041 
00042 #ifdef HAVE_SYS_STAT_H
00043 #include <sys/stat.h>
00044 #endif
00045 
00046 #include "monitor.h"
00047 
00048 
00062 /* ------------------------------------------------------------------ Public */
00063 
00064 
00068 void init_files() {
00069 
00070   char pidfile[STRLEN];
00071 
00072   /* Check if the pidfile was already set during configfile parsing */
00073   if(Run.pidfile == NULL) {
00074 
00075     /* Set the location of this programs pidfile */
00076     if(! getuid()) {
00077 
00078       snprintf(pidfile, STRLEN, "%s/%s", MYPIDDIR, MYPIDFILE);
00079 
00080     } else {
00081 
00082       snprintf(pidfile, STRLEN, "%s/.%s", Run.Env.home, MYPIDFILE);
00083 
00084     }
00085 
00086     Run.pidfile= xstrdup(pidfile);
00087 
00088   }
00089   
00090   Run.timestamp= get_timestamp(Run.controlfile, S_IFREG);
00091   
00092 }
00093 
00094 
00098 void finalize_files() {
00099   
00100   unlink(Run.pidfile);
00101 
00102 }
00103 
00104 
00112 time_t get_timestamp(char *object, mode_t type) {
00113   
00114   struct stat buf;
00115 
00116   ASSERT(object);
00117 
00118   if(! stat(object, &buf)) {
00119     
00120     if(((type == S_IFREG) && S_ISREG(buf.st_mode)) ||
00121        ((type == S_IFDIR) && S_ISDIR(buf.st_mode)) ||
00122        ((type == (S_IFREG|S_IFDIR)) && (S_ISREG(buf.st_mode) ||
00123                     S_ISDIR(buf.st_mode)))
00124        ) {
00125       
00126        return MAXIMUM(buf.st_mtime, buf.st_ctime);
00127 
00128      } else {
00129 
00130        log("%s: Invalid object type - %s\n", prog, object);
00131 
00132      }
00133 
00134   }
00135 
00136   return FALSE;
00137   
00138 }
00139 
00140 
00147 char *find_rcfile() {
00148 
00149   char *rcfile= xmalloc(STRLEN);
00150   
00151   snprintf(rcfile, STRLEN, "%s/.%s", Run.Env.home, MONITRC);
00152   
00153   if(exist_file(rcfile)) {
00154     
00155     return (rcfile);
00156     
00157   }
00158 
00159   if(exist_file(MONITRC)) {
00160     
00161     memset(rcfile, 0, STRLEN);
00162     snprintf(rcfile, STRLEN, "%s/%s", Run.Env.cwd, MONITRC);
00163     
00164     return (rcfile);
00165     
00166   }
00167   
00168   memset(rcfile, 0, STRLEN);
00169   snprintf(rcfile, STRLEN, "/etc/%s", MONITRC);
00170   
00171   if(exist_file(rcfile)) 
00172     return (rcfile);
00173   
00174   log("%s: Cannot find the control file at ~/.%s, ./%s or at /etc/%s\n",
00175       prog, MONITRC, MONITRC, MONITRC);
00176   
00177   exit(1);
00178   
00179 }
00180 
00181 
00188 int create_pidfile(char *pidfile) {
00189   
00190   FILE *F= NULL;
00191 
00192   ASSERT(pidfile);
00193   
00194   umask(PIDMASK);
00195   
00196   if ((F= fopen(pidfile,"w")) == (FILE *)NULL) {
00197     
00198     log("%s: Error opening pidfile '%s' for writing -- %s\n",
00199     prog, pidfile, STRERROR);
00200     
00201     return(FALSE);
00202     
00203   }
00204   
00205   fprintf(F, "%d", (int)getpid());
00206   fclose(F);
00207 
00208   return TRUE;
00209   
00210 }
00211 
00212 
00218 int is_rcfile_changed() {
00219   
00220   return(get_timestamp(Run.controlfile, S_IFREG) != Run.timestamp);
00221   
00222 }
00223 
00224 
00233 int check_rcfile(char *rcfile) {
00234 
00235   ASSERT(rcfile);
00236   
00237   return check_file(rcfile, "control file", S_IRUSR | S_IWUSR | S_IXUSR);
00238   
00239 }
00240 
00241 
00247 int isreg_file(char *file) {
00248   
00249   struct stat buf;
00250   
00251   ASSERT(file);
00252 
00253   return (stat(file, &buf) == 0 && S_ISREG(buf.st_mode));
00254   
00255 }
00256 
00257 
00263 int exist_file(char *file) {
00264   
00265   struct stat buf;
00266   
00267   ASSERT(file);
00268 
00269   return (stat(file, &buf) == 0);
00270   
00271 }
00272 
00273 
00284 int check_file(char *filename, char *description, int permmask) {
00285 
00286   struct stat buf;
00287   errno= 0;
00288 
00289   ASSERT(filename);
00290   ASSERT(description);
00291 
00292   if(lstat(filename, &buf) < 0) {
00293     
00294     log("%s: Cannot stat the %s '%s' -- %s\n",
00295     prog, description, filename, STRERROR);
00296 
00297     return FALSE;
00298     
00299   }
00300     
00301   if(S_ISLNK(buf.st_mode)) {
00302     
00303     log("%s: The %s '%s' must not be a symbolic link.\n",
00304     prog, description, filename);
00305     
00306     return(FALSE);
00307     
00308   }
00309 
00310   if(!S_ISREG(buf.st_mode)) {
00311     
00312     log("%s: The %s '%s' is not a regular file.\n", 
00313     prog, description,  filename);
00314     
00315     return FALSE;
00316 
00317   }
00318 
00319   if(buf.st_uid != geteuid())  {
00320     
00321     log("%s: The %s '%s' must be owned by you.\n", 
00322     prog, description, filename);
00323       
00324     return FALSE;
00325     
00326   }
00327 
00328   if((buf.st_mode & 0777 ) & ~permmask) {
00329 
00330     /* 
00331        Explanation: 
00332 
00333            buf.st_mode & 0777 ->  We just want to check the
00334                                   permissions not the file type... 
00335                                   we did it already!
00336            () & ~permmask ->      We check if there are any other
00337                                   permissions set than in permmask 
00338     */
00339 
00340     log("%s: The %s '%s' must have permissions no more "
00341     "than -%c%c%c%c%c%c%c%c%c (0%o); "
00342     "right now permissions are -%c%c%c%c%c%c%c%c%c (0%o).\n", 
00343     prog, description, filename, 
00344     permmask&S_IRUSR?'r':'-',
00345     permmask&S_IWUSR?'w':'-',
00346     permmask&S_IXUSR?'x':'-',
00347     permmask&S_IRGRP?'r':'-',
00348     permmask&S_IWGRP?'w':'-',
00349     permmask&S_IXGRP?'x':'-',
00350     permmask&S_IROTH?'r':'-',
00351     permmask&S_IWOTH?'w':'-',
00352     permmask&S_IXOTH?'x':'-',
00353     permmask&0777,
00354     buf.st_mode&S_IRUSR?'r':'-',
00355     buf.st_mode&S_IWUSR?'w':'-',
00356     buf.st_mode&S_IXUSR?'x':'-',
00357     buf.st_mode&S_IRGRP?'r':'-',
00358     buf.st_mode&S_IWGRP?'w':'-',
00359     buf.st_mode&S_IXGRP?'x':'-',
00360     buf.st_mode&S_IROTH?'r':'-',
00361     buf.st_mode&S_IWOTH?'w':'-',
00362     buf.st_mode&S_IXOTH?'x':'-',
00363     buf.st_mode& 0777);
00364     
00365     return FALSE;
00366     
00367   }
00368 
00369   return TRUE;
00370 
00371 }
00372