Ejemplo n.º 1
0
static void
apm_periodic_check(struct apm_softc *sc)
{
	int error;
	u_int event_code, event_info;


	/*
	 * tell the BIOS we're working on it, if asked to do a
	 * suspend/standby
	 */
	if (apm_op_inprog)
		(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS,
		    APM_LASTREQ_INPROG);

	while ((error = (*sc->sc_ops->aa_get_event)(sc->sc_cookie, &event_code,
	    &event_info)) == 0 && !apm_damn_fool_bios)
		apm_event_handle(sc, event_code, event_info);

	if (error != APM_ERR_NOEVENTS)
		apm_perror("get event", error);
	if (apm_suspends) {
		apm_op_inprog = 0;
		apm_suspend(sc);
	} else if (apm_standbys || apm_userstandbys) {
		apm_op_inprog = 0;
		apm_standby(sc);
	}
	apm_suspends = apm_standbys = apm_battlow = apm_userstandbys = 0;
	apm_damn_fool_bios = 0;
}
Ejemplo n.º 2
0
int 
main(int argc, char *argv[])
{
	int	c, fd;
	int     dosleep = 0, all_info = 1, apm_status = 0, batt_status = 0;
	int     display = -1, batt_life = 0, ac_status = 0, standby = 0;
	int	batt_time = 0, delta = 0, enable = -1, haltcpu = -1;
	int	bioscall_available = 0;
	size_t	cmos_wall_len = sizeof(cmos_wall);

	if (sysctlbyname("machdep.wall_cmos_clock", &cmos_wall, &cmos_wall_len,
	    NULL, 0) == -1)
		err(1, "sysctlbyname(machdep.wall_cmos_clock)");

	while ((c = getopt(argc, argv, "abe:h:lRr:stzd:Z")) != -1) {
		switch (c) {
		case 'a':
			ac_status = 1;
			all_info = 0;
			break;
		case 'b':
			batt_status = 1;
			all_info = 0;
			break;
		case 'd':
			display = is_true(optarg);
			all_info = 0;
			break;
		case 'l':
			batt_life = 1;
			all_info = 0;
			break;
		case 'R':
			delta = -1;
			break;
		case 'r':
			delta = atoi(optarg);
			break;
		case 's':
			apm_status = 1;
			all_info = 0;
			break;
		case 'e':
			enable = is_true(optarg);
			all_info = 0;
			break;
		case 'h':
			haltcpu = is_true(optarg);
			all_info = 0;
			break;
		case 't':
			batt_time = 1;
			all_info = 0;
			break;
		case 'z':
			dosleep = 1;
			all_info = 0;
			break;
		case 'Z':
			standby = 1;
			all_info = 0;
			break;
		case '?':
		default:
			usage();
		}
		argc -= optind;
		argv += optind;
	}
	if (haltcpu != -1 || enable != -1 || display != -1 || delta || dosleep
	    || standby) {
		fd = open(APMDEV, O_RDWR);
		bioscall_available = 1;
	} else if ((fd = open(APMDEV, O_RDWR)) >= 0)
		bioscall_available = 1;
	else
		fd = open(APMDEV, O_RDONLY);
	if (fd == -1)
		err(1, "can't open %s", APMDEV);
	if (enable != -1)
		apm_enable(fd, enable);
	if (haltcpu != -1)
		apm_haltcpu(fd, haltcpu);
	if (delta)
		apm_set_timer(fd, delta);
	if (dosleep)
		apm_suspend(fd);
	else if (standby)
		apm_standby(fd);
	else if (delta == 0) {
		struct apm_info info;

		apm_getinfo(fd, &info);
		if (all_info)
			print_all_info(fd, &info, bioscall_available);
		if (ac_status)
			printf("%d\n", info.ai_acline);
		if (batt_status)
			printf("%d\n", info.ai_batt_stat);
		if (batt_life)
			printf("%d\n", info.ai_batt_life);
		if (apm_status)
			printf("%d\n", info.ai_status);
		if (batt_time)
			printf("%d\n", info.ai_batt_time);
		if (display != -1)
			apm_display(fd, display);
	}
	close(fd);
	exit(0);
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
  int i, rtcfd, retval;
  struct rtc_time rtc_tm;
  struct tm kernel_tm;
  time_t kernel_time, new_time, old_time;
  char *p;
  int c;
  int apmfd=-1;       /* APM device file descriptor */
  int isoffset;       /* setting time offset */
  int hour, minute;   /* alarm time requested */
  int hour1, minute1;  /* backup for precise_mode */
  int flag;
  static int suspend_mode=0, wait_mode=0, debug_mode=0, precise_mode=0,
    noapm_mode=0;

  while (1) {
    /* int this_option_optind = optind ? optind : 1; */
    int option_index = 0;
    static struct  option long_options[] = {
      {"help",    0, 0, 'h'},
      {"debug",   0, 0, 'd'},
      {"version", 0, 0, 'V'},
      {"suspend", 0, 0, 's'},
      {"standby", 0, 0, 'S'},
      {"wait",    0, 0, 'w'},
      {"noapm",   0, 0, 'n'},
      {"precise",   0, 0, 'p'},
      {0,0,0,0}
    };

    c = getopt_long(argc, argv, "hdVsSwnp", long_options, &option_index);
    if (c == -1) break;
    switch(c)
      {
      case 'h':
	usage();
        exit(0);
      case 'V':
	version();
        exit(0);
      case 'd':
	debug_mode=1;
	break;
      case 's': /*suspend*/
	suspend_mode=0;
	break;
      case 'S': /*standby*/
	suspend_mode=1;
	break;
      case 'n': /*noapm*/
	noapm_mode=1;
	wait_mode=1;
	break;
      case 'w':
	wait_mode=!precise_mode;
	break;
      case 'p':/*precise*/
	precise_mode=1;
	break;
      case '?': /*unknown option*/
	exit(1);
      default:
	fprintf(stderr,"unknown option return %d\n", c);
	exit(1);
      }
  } /* end while (1) */
  if (optind < argc) {
    if (optind+1 != argc) {
      fprintf(stderr,"To many arguments.\n"); usage();
      exit(1);
    }
    p=argv[optind];
    isoffset=0;
    if (p[0]=='+') { p++; isoffset=1;}
    if (2!=sscanf(p, "%d:%d", &hour, &minute)) {
      fprintf(stderr,"apmsleep: Bad argument(s)\n");
      exit(1);
    }
    hour1=hour; minute1=minute; /* backup */
  } else {
    fprintf(stderr,"apmsleep: missing argument.\n"); usage();
    exit(1);
  }

  if (noapm_mode) suspend_mode=2;

  /* argument processing finished */

  if (geteuid()!=0) {
    fprintf(stderr, "apmsleep: warning: This program must be run as root "
	      "or have the SUID attribute set\n");      
  }

  /* check if APM is supported */
  if (apm_exists()) {
    fprintf(stderr, "apmsleep: Your kernel does not support APM.\n");
    fprintf(stderr, "apmsleep: Recompile kernel with APM and "
	    "/dev/rtc support\n");
    exit(1);
  }
  if (!noapm_mode) {
    apmfd=open(APM_DEVICE, O_WRONLY);
    if (apmfd < 0) {
      fprintf(stderr, "apmsleep: Cannot open APM device.\n");
      exit(1);
    }
  }

  rtcfd = open ("/dev/rtc", O_RDONLY);
  if (errno == EACCES) {
    fprintf(stderr, "apmsleep: You don't have permission to "
	    "access /dev/rtc\n");      
    fprintf(stderr, "apmsleep: The program must be run as root "
	    "or have the SUID attribute set\n");      
    exit(errno);
  }
  if (rtcfd ==  -1) {
    perror("/dev/rtc");

    fprintf(stderr, "apmsleep: Your kernel does not support "
	    "the real time clock device\n");
    fprintf(stderr, "apmsleep: Recompile kernel with APM and "
	    "/dev/rtc support\n");
    exit(errno);
  }
  
  /* Read the RTC time/date */
  retval = ioctl(rtcfd, RTC_RD_TIME, &rtc_tm);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }
  /* Read Kernel time/date */
  time(&kernel_time);
  kernel_tm=*localtime(&kernel_time);
  
  if (debug_mode) {
    printf("Current RTC time is %02d:%02d:%02d.\n",
	   rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
    printf("Current local time is %02d:%02d:%02d.\n",
	   kernel_tm.tm_hour, kernel_tm.tm_min, kernel_tm.tm_sec);
  }

  /* set alarm time in RTC */
  if (isoffset) {
    if (hour == 0 && minute == 0)
      exit(0);
    hour+=(int)rtc_tm.tm_hour;
    minute+=(int)rtc_tm.tm_min;
    hour1+=(int)kernel_tm.tm_hour;
    minute1+=(int)kernel_tm.tm_min;
  } else {
    /* Special case - wake-up time equal current time
       this may cause to systems to crash according to
       a user report. Therefore, we do not suspend in this case.  */
    if (hour == kernel_tm.tm_hour && minute == kernel_tm.tm_min) {
      printf("Wake-up time equal to current time. Suspend not required\n");
      exit(0);
    }
    rtc_tm.tm_sec=0;
    /* here we take difference between RTC and localtime into account */
    minute+=(int)rtc_tm.tm_min - (int)kernel_tm.tm_min;
    hour+=(int)rtc_tm.tm_hour - (int)kernel_tm.tm_hour;
  }
  while (minute<0) {minute +=60; hour--; }
  while (minute>=60) {minute -=60; hour++; }
  while (hour < 0) hour += 24;
  hour %= 24;
  rtc_tm.tm_min = minute;
  rtc_tm.tm_hour = hour;
  if (debug_mode)
    printf("Setting RTC alarm time to %02d:%02d:%02d.\n",
	   hour, minute, rtc_tm.tm_sec);

  retval = ioctl(rtcfd, RTC_ALM_SET, &rtc_tm);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  /* Read back the current alarm settings */
  retval = ioctl(rtcfd, RTC_ALM_READ, &rtc_tm);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  if (debug_mode) 
    printf("RTC alarm time now set to %02d:%02d:%02d.\n",
	   rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
  
  /* Enable alarm interrupts */
  retval = ioctl(rtcfd, RTC_AIE_ON, 0);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  /* Save time before suspending */
  time(&new_time);
  kernel_time=new_time;

  if (fork()==0) {
    /* suspend system -- called from within a child, to make
     * sure we don't miss the time leap
     */
    switch(suspend_mode) {
    case 0:
      apm_suspend(apmfd);
      break;
    case 1:
      apm_standby(apmfd);
      break;
    }
    exit(0);
  }

  if (debug_mode) {
    printf("Waiting until clock jumps\n");
    fflush(stdout);
  }


  flag=1;  /* Note: flag is used as exit value */
  if (precise_mode) {
    /* wait for clock match alarm time */
    if (debug_mode) printf("Wait for wakeup time\n");
    do {
      int diff;
      /* Read Kernel time/date */
      time(&kernel_time);
      kernel_tm=*localtime(&kernel_time);
      if (debug_mode) 
	printf("Time: %02d:%02d:%02d, wakeup time: %02d:%02d:%02d\n",
	       kernel_tm.tm_hour, kernel_tm.tm_min, kernel_tm.tm_sec,
	       hour1, minute1, 0);
      diff= hour1*60 + minute1 - kernel_tm.tm_hour*60 - kernel_tm.tm_min;
      diff %= (24*60);
      flag=(diff!=0 && diff!=-1);
      if (flag) sleep(10);
    } while (flag);
  } else {
    /* wait for the actual sleep event */
    do {
      old_time=new_time;
      sleep(2);
      time(&new_time);
      flag=difftime(new_time,old_time)<10.0;
      /* check for time out */
      if (flag && wait_mode==0 && difftime(new_time,kernel_time)>120.0)
	break; /* timeout, flag is 1 */
    } while (flag);

    if (flag) 
      fprintf(stderr,"Time out -- no time leap happened\n");
    else if (debug_mode)
      printf("Time leap detected\n");
  }

  /* Waiting for child to finish */
  wait(&i);

  /* Disable alarm interrupts */
  retval = ioctl(rtcfd, RTC_AIE_OFF, 0);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }
  close(rtcfd);
  if (!noapm_mode) close(apmfd);
  
  return flag;
}