files.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2003 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_SYS_TYPES_H
00035 #include <sys/types.h>
00036 #endif
00037 
00038 #ifdef HAVE_SYS_STAT_H
00039 #include <sys/stat.h>
00040 #endif
00041 
00042 #ifdef HAVE_UNISTD_H
00043 #include <unistd.h>
00044 #endif
00045 
00046 #ifdef HAVE_FCNTL_H
00047 #include <fcntl.h>
00048 #endif
00049 
00050 
00051 #include "monitor.h"
00052 
00053 
00067 /* ------------------------------------------------------------------ Public */
00068 
00069 
00073 void init_files() {
00074 
00075   char pidfile[STRLEN];
00076 
00077   /* Check if the pidfile was already set during configfile parsing */
00078   if(Run.pidfile == NULL) {
00079 
00080     /* Set the location of this programs pidfile */
00081     if(! getuid()) {
00082 
00083       snprintf(pidfile, STRLEN, "%s/%s", MYPIDDIR, MYPIDFILE);
00084 
00085     } else {
00086 
00087       snprintf(pidfile, STRLEN, "%s/.%s", Run.Env.home, MYPIDFILE);
00088 
00089     }
00090 
00091     Run.pidfile= xstrdup(pidfile);
00092 
00093   }
00094   
00095 }
00096 
00097 
00101 void finalize_files() {
00102   
00103   unlink(Run.pidfile);
00104 
00105 }
00106 
00107 
00115 time_t get_timestamp(char *object, mode_t type) {
00116   
00117   struct stat buf;
00118 
00119   ASSERT(object);
00120 
00121   if(! stat(object, &buf)) {
00122     
00123     if(((type == S_IFREG) && S_ISREG(buf.st_mode)) ||
00124        ((type == S_IFDIR) && S_ISDIR(buf.st_mode)) ||
00125        ((type == (S_IFREG|S_IFDIR)) && (S_ISREG(buf.st_mode) ||
00126                     S_ISDIR(buf.st_mode)))
00127        ) {
00128       
00129        return MAXIMUM(buf.st_mtime, buf.st_ctime);
00130 
00131      } else {
00132 
00133        log("%s: Invalid object type - %s\n", prog, object);
00134 
00135      }
00136 
00137   }
00138 
00139   return FALSE;
00140   
00141 }
00142 
00143 
00150 char *find_rcfile() {
00151 
00152   char *rcfile= xmalloc(STRLEN);
00153   
00154   snprintf(rcfile, STRLEN, "%s/.%s", Run.Env.home, MONITRC);
00155   
00156   if(exist_file(rcfile)) {
00157     
00158     return (rcfile);
00159     
00160   }
00161 
00162   if(exist_file(MONITRC)) {
00163     
00164     memset(rcfile, 0, STRLEN);
00165     snprintf(rcfile, STRLEN, "%s/%s", Run.Env.cwd, MONITRC);
00166     
00167     return (rcfile);
00168     
00169   }
00170   
00171   memset(rcfile, 0, STRLEN);
00172   snprintf(rcfile, STRLEN, "/etc/%s", MONITRC);
00173   
00174   if(exist_file(rcfile)) 
00175     return (rcfile);
00176   
00177   log("%s: Cannot find the control file at ~/.%s, ./%s or at /etc/%s\n",
00178       prog, MONITRC, MONITRC, MONITRC);
00179   
00180   exit(1);
00181   
00182 }
00183 
00184 
00191 int create_pidfile(char *pidfile) {
00192   
00193   FILE *F= NULL;
00194 
00195   ASSERT(pidfile);
00196   
00197   umask(PIDMASK);
00198   
00199   if ((F= fopen(pidfile,"w")) == (FILE *)NULL) {
00200     
00201     log("%s: Error opening pidfile '%s' for writing -- %s\n",
00202     prog, pidfile, STRERROR);
00203     
00204     return(FALSE);
00205     
00206   }
00207   
00208   fprintf(F, "%d", (int)getpid());
00209   fclose(F);
00210 
00211   return TRUE;
00212   
00213 }
00214 
00215 
00224 int check_rcfile(char *rcfile) {
00225 
00226   ASSERT(rcfile);
00227   
00228   return check_file(rcfile, "control file", S_IRUSR | S_IWUSR | S_IXUSR);
00229   
00230 }
00231 
00232 
00238 int isreg_file(char *file) {
00239   
00240   struct stat buf;
00241   
00242   ASSERT(file);
00243 
00244   return (stat(file, &buf) == 0 && S_ISREG(buf.st_mode));
00245   
00246 }
00247 
00248 
00254 int exist_file(char *file) {
00255   
00256   struct stat buf;
00257   
00258   ASSERT(file);
00259 
00260   return (stat(file, &buf) == 0);
00261   
00262 }
00263 
00264 
00275 int check_file(char *filename, char *description, int permmask) {
00276 
00277   struct stat buf;
00278   errno= 0;
00279 
00280   ASSERT(filename);
00281   ASSERT(description);
00282 
00283   if(lstat(filename, &buf) < 0) {
00284     
00285     log("%s: Cannot stat the %s '%s' -- %s\n",
00286     prog, description, filename, STRERROR);
00287 
00288     return FALSE;
00289     
00290   }
00291     
00292   if(S_ISLNK(buf.st_mode)) {
00293     
00294     log("%s: The %s '%s' must not be a symbolic link.\n",
00295     prog, description, filename);
00296     
00297     return(FALSE);
00298     
00299   }
00300 
00301   if(!S_ISREG(buf.st_mode)) {
00302     
00303     log("%s: The %s '%s' is not a regular file.\n", 
00304     prog, description,  filename);
00305     
00306     return FALSE;
00307 
00308   }
00309 
00310   if(buf.st_uid != geteuid())  {
00311     
00312     log("%s: The %s '%s' must be owned by you.\n", 
00313     prog, description, filename);
00314       
00315     return FALSE;
00316     
00317   }
00318 
00319   if((buf.st_mode & 0777 ) & ~permmask) {
00320 
00321     /* 
00322        Explanation: 
00323 
00324            buf.st_mode & 0777 ->  We just want to check the
00325                                   permissions not the file type... 
00326                                   we did it already!
00327            () & ~permmask ->      We check if there are any other
00328                                   permissions set than in permmask 
00329     */
00330 
00331     log("%s: The %s '%s' must have permissions no more "
00332     "than -%c%c%c%c%c%c%c%c%c (0%o); "
00333     "right now permissions are -%c%c%c%c%c%c%c%c%c (0%o).\n", 
00334     prog, description, filename, 
00335     permmask&S_IRUSR?'r':'-',
00336     permmask&S_IWUSR?'w':'-',
00337     permmask&S_IXUSR?'x':'-',
00338     permmask&S_IRGRP?'r':'-',
00339     permmask&S_IWGRP?'w':'-',
00340     permmask&S_IXGRP?'x':'-',
00341     permmask&S_IROTH?'r':'-',
00342     permmask&S_IWOTH?'w':'-',
00343     permmask&S_IXOTH?'x':'-',
00344     permmask&0777,
00345     buf.st_mode&S_IRUSR?'r':'-',
00346     buf.st_mode&S_IWUSR?'w':'-',
00347     buf.st_mode&S_IXUSR?'x':'-',
00348     buf.st_mode&S_IRGRP?'r':'-',
00349     buf.st_mode&S_IWGRP?'w':'-',
00350     buf.st_mode&S_IXGRP?'x':'-',
00351     buf.st_mode&S_IROTH?'r':'-',
00352     buf.st_mode&S_IWOTH?'w':'-',
00353     buf.st_mode&S_IXOTH?'x':'-',
00354     buf.st_mode& 0777);
00355     
00356     return FALSE;
00357     
00358   }
00359 
00360   return TRUE;
00361 
00362 }
00363