/* 
** cdstatus
**
** Copyright Darryl Bond, 2005
**
** This program is under the GNU General Public License (GPL)
**
**
** Purpose: Poll the supplied CDROM device
** and execute a script when CD has been inserted or removed
** Log events to syslog
*/

#include <sys/types.h>
#include <sys/stat.h>		// mkdir
#include <sys/ioctl.h>		// ioctls
#include <unistd.h>		// lseek, read. etc
#include <fcntl.h>		// O_RDONLY etc.
#include <linux/iso_fs.h>	// isofs constants
#include <linux/cdrom.h>	// old ioctls for cdrom#include <string>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <libintl.h>
#include <errno.h>
#include <syslog.h>




int main(int argc,char *argv[]){
  int cdromfd;
  char cmd[100];
  int status = 0;
  struct stat buf;
  
  openlog("cdstatus",LOG_PID,LOG_DAEMON);
  if (argc < 2 ){
    syslog(LOG_ERR,"Usage: %s cdrom-device",argv[0]);
    closelog();
    return(1);
  }
  if (lstat(argv[1],&buf) <0 ) {
    syslog(LOG_ERR,"Device %s does not exist",argv[1]);
    closelog();
    return(1);
  }

  daemon_init();

  for (;;){
    cdromfd = open(argv[1], O_RDONLY | O_NONBLOCK | O_EXCL);
    if ( cdromfd < 1 ){
      syslog(LOG_ERR,"Device %s cannot be opened",argv[1]);
      closelog();
      return(1);
    }

   
    if (cdromfd >= 0) {      
      int ret = ioctl(cdromfd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
      switch(ret) {
      case CDS_DISC_OK:
	if ( ! status  ){
	  
	  sprintf(cmd,"/usr/sbin/cdrom mount %s",argv[1]);
	  system(cmd);
	  syslog(LOG_DEBUG,"mount %s: %m",argv[1]);
	  status = 1;
	}
	break;
      case CDS_TRAY_OPEN:
      case CDS_NO_DISC:
	if ( status  ){	
	  sprintf(cmd,"/usr/sbin/cdrom umount %s",argv[1]);
	  system(cmd);
	  syslog(LOG_DEBUG,"umount %s: %m",argv[1]);
	  status = 0;
	}
	break;
      case CDS_NO_INFO:
	syslog(LOG_ERR,"%s: cdrom no info",argv[0]);
	break;
      case CDS_DRIVE_NOT_READY:
	syslog(LOG_ERR,"%s: cdrom drive not ready",argv[0]);
	break;
      default:
	syslog(LOG_ERR,"%s: unknown cdrom error",argv[0]);
      }
      close(cdromfd);
    }
    sleep(2);  
  }
  closelog();
}

int daemon_init(void) {
  pid_t pid;

  if ((pid = fork()) <0 )
    return(-1);
  else if (pid !=0)
    exit(0);

  /* child continues */
  setsid(); /* become session leader */
  chdir("/");
  umask(0);
  return(0);
}
  
    
