2015年7月26日 星期日

[C] Monitor the state of a file


/*
This program (existence.c) constantly monitors if an arbitrary
file exists and returns its size
It comes with no support and Wiki-UX.info makes no representations as to its
fitness for purpose. It is up to whoever uses this program to ensure
that whatever functionality it provides is what they require.
(c) Wiki-UX.info (2010)

Default time delay is 1 second
Usage: existence [-t time] -f filename

2009.11.23 - Added code to detect and report inode number changes.
*/

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <pwd.h>
# include <grp.h>
# include <signal.h>
# include <fcntl.h>
# include <time.h>
# include <sys/types.h>
# include <sys/stat.h>

/* Public variables */
FILE *fp;
int fo;

/* Prototypes */
int errors(int errorcode);
void catch_int(int sig_num);
void catch_term(int sig_num);

int main(int argc, char** argv) {
struct stat mystat;
struct passwd *pwd;
struct group *grp;
struct tm *ts;
int i, status;
signed int inodenum=-1;
char myfile[256];
char fdate[80];
int sleeptime = 1; /* Default sleep time is 1 second */

signal(SIGINT, catch_int); /* Traps SIGINT */
signal(SIGTERM, catch_term); /* Traps SIGINT */

/* Read command options */
for(i = 1; i < argc; i++) {
 if(argv[i][0] == '-') {
 switch (argv[i][1]) {
  case 't':
   sleeptime = atoi(argv[i+1]);
   break;
  case 'f':
   strcpy(myfile, argv[i+1]);
   break;
  default:
   return(errors(1));
  }
 }
}

/* Verify that -f filename is defined */
if(strlen(myfile) < 1)
 return(errors(1));

printf("PID: %d\n", getpid());

/* Check that the file exists and prints file information */
while(1) {
 fo = open(myfile, O_RDONLY);
 if (fo != -1) {
  status = fstat(fo, &mystat);
  close(fo);

/* Compares previous inode with current inode and returns a warning */
/* Set the current inode to inum if this is the first pass */
  if(inodenum == -1)
     inodenum = mystat.st_ino;

/* Return information if the inode change from previous file */
  if(inodenum != mystat.st_ino) {
     errors(3);
     inodenum = mystat.st_ino;
  }

  printf("%d\t", inodenum);

  if(pwd = getpwuid(mystat.st_uid))
     fprintf(stdout, "%s\t", pwd->pw_name);
  else
     fprintf(stdout, "%d\t", mystat.st_uid);

  if(grp = getgrgid(mystat.st_gid))
     fprintf(stdout, "%s\t", grp->gr_name);
  else
     fprintf(stdout, "%d\t", mystat.st_gid);

  ts = localtime(&mystat.st_mtime);
  strftime(fdate, sizeof(fdate), "%a %Y-%m-%d %H:%M:%S %Z", ts);
  printf("%s\t", fdate);

  fprintf(stdout, "%d\t%s\n",
     mystat.st_size,
     myfile);
  } else errors(2);
sleep(sleeptime);
 }
}

/* Error message handler */
int errors(int errorcode) {

switch (errorcode) {
   case 1:
      fprintf(stderr, "usage: existence [-t delay] -f filename\n");
      break;
   case 2:
      fprintf(stderr, "Cannot open file or directory!\n");
      break;
   case 3:
      fprintf(stderr, "Inode Number since the previous test!\n");
      break;
   }
return errorcode;
}

/* UNIX Signal handlers */
void catch_int(int sig_num)
{
    signal(SIGINT, catch_int);
        if (fo != -1)
         close(fo);
    fprintf(stderr, "Program interrupted\n");
        exit(0);
}

void catch_term(int sig_num)
{
    signal(SIGTERM, catch_int);
        if (fo != -1)
         close(fo);
    fprintf(stderr, "Program terminated.\n");
        exit(0);
}
Reference:

0 意見:

張貼留言