Beispiel #1
0
/* Return a file descriptor for the apm_bios device, or -1 if there is an
 * error.  Is this method secure?  Should we make the device in /dev
 * instead of /tmp? 
 *
 * apenwarr 2001/05/11: just throw out the weird temporary device file stuff.
 *	It was only for ancient kernel versions anyway.
 */
int apm_open(void)
{
    int fd;
    apm_info i;

    if (access(APM_PROC, R_OK) || apm_read(&i) == 1)
	return -1;
    if (i.driver_version[0] >= '1')
    {
	if ((fd = open(APM_DEVICE, O_RDWR)) < 0)
	{
	    /* Try to create it.  This is reasonable
	     * for backward compatibility.
	     */
	    if (mknod(APM_DEVICE, S_IFCHR | S_IRUSR | S_IWUSR, apm_dev()))
	    {
		unlink(APM_DEVICE);
		return -1;
	    }
	    fd = open(APM_DEVICE, O_RDWR);
	}
	
	return fd;
    }
    
    return -1;
}
Beispiel #2
0
/* If APM support of the right version exists in kernel, return zero.
 * Otherwise, return 1 if no support exists, or 2 if it is the wrong
 * version.  *NOTE* The sense of the return value is not intuitive.
 */
int apm_exists(void)
{
    apm_info i;

    if (access(APM_PROC, R_OK))
	return 1;
    return apm_read(&i);
}
Beispiel #3
0
Datei: apm.c Projekt: OLSR/olsrd
int
apm_init(void)
{
  struct olsr_apm_info ApmInfo;

  OLSR_PRINTF(3, "Initializing APM\n");

  if (apm_read(&ApmInfo) < 0)
    return -1;

  apm_printinfo(&ApmInfo);

  return 0;
}
Beispiel #4
0
/*
 * If APM support of the right version exists in kernel, return zero.
 * Otherwise, return 1 if no support exists, or 2 if it is the wrong
 * version.  *NOTE* The sense of the return value is not intuitive.
 */
int apm_exists(void)
{
    int fd;
    apm_info i;

    /* This will force auto-load of the apm module if necessary. */
    fd = open(APM_DEVICE, O_WRONLY);
    if (fd >= 0)
	close(fd);

    if (access(APM_PROC, R_OK))
	return 1;
    return apm_read(&i);
}
static const char *
apm_readinfo (BatteryStatus *status)
{
  /* Code for Linux by Thomas Hood <*****@*****.**>. apm_read() will
     read from /proc/... instead and we do not need to open the device
     ourselves.
  */
  if (DEBUG) g_print("apm_readinfo() (Linux)\n");

  /* ACPI support added by Lennart Poettering <*****@*****.**> 10/27/2001
   * Updated by David Moore <*****@*****.**> 5/29/2003 to poll less and
   *   use ACPI events. */
  if (using_acpi && acpiinfo.event_fd >= 0) {
    if (acpi_count <= 0) {
      /* Only call this one out of 30 calls to apm_readinfo() (every 30 seconds)
       * since reading the ACPI system takes CPU cycles. */
      acpi_count=30;
      acpi_linux_read(&apminfo, &acpiinfo);
    }
    acpi_count--;
  }
  /* If we lost the file descriptor with ACPI events, try to get it back. */
  else if (using_acpi) {
      if (acpi_linux_init(&acpiinfo)) {
          acpiwatch = g_io_add_watch (acpiinfo.channel,
              G_IO_IN | G_IO_ERR | G_IO_HUP,
              acpi_callback, NULL);
          acpi_linux_read(&apminfo, &acpiinfo);
      }
  }
  else
    apm_read(&apminfo);

  status->present = TRUE;
  status->on_ac_power = apminfo.ac_line_status ? 1 : 0;
  status->percent = (guint) apminfo.battery_percentage;
  status->charging = (apminfo.battery_flags & 0x8) ? TRUE : FALSE;
  status->minutes = apminfo.battery_time;

  return NULL;
}
Beispiel #6
0
/*
 * Look up the device number of the apm_bios device.
 */
dev_t apm_dev(void)
{
    FILE *str;
    static int cached = -1;
    char buf[80];
    char *pt;
    apm_info i;

    if (cached >= 0)
	return cached;

    if (access(APM_PROC, R_OK) || apm_read(&i) == 1)
	return cached = -1;
    if (i.driver_version[0] == '1')
	return cached = makedev(10, 134);

    if (!(str = fopen(APM_DEV, "r")))
	return -1;
    while (fgets(buf, sizeof(buf) - 1, str))
    {
	buf[sizeof(buf) - 1] = '\0';
	for (pt = buf; *pt && isspace(*pt); ++pt);	/* skip leading spaces */
	for (; *pt && !isspace(*pt); ++pt);	/* find next space */
	if (isspace(*pt))
	{
	    *pt++ = '\0';
	    pt[strlen(pt) - 1] = '\0';	/* get rid of newline */
	    if (!strcmp(pt, APM_NAME))
	    {
		fclose(str);
		return cached = makedev(atoi(buf), 0);
	    }
	}
    }
    fclose(str);
    return cached = -1;
}
Beispiel #7
0
void get_power_status(pm_status *power_status)
{
  /* Is this an ACPI system? */
  if (pm_type == PM_ACPI)
  {
    static ACPIinfo  acpiinfo;
    static ACADstate acadstate;
    static ACPIstate acpistate;

    read_acpi_info(&acpiinfo, Battery - 1);
    read_acpi_state(&acpistate, &acpiinfo, Battery - 1);
    read_acad_state(&acadstate);

    /* Check if we are on ac power */
    ac_on_line = power_status->ac_on_line = acadstate.state;

    /* Check to see if we are charging. */
    if (acpistate.state == CHARGING) power_status->battery_charging=1;
    else power_status->battery_charging=0;

    /* Check battery time and percentage */
    power_status->battery_time = acpistate.rtime;
    power_status->battery_percentage = acpistate.percentage;
    if (power_status->battery_percentage > 100) power_status->battery_percentage = 100;
    battery_percentage = power_status->battery_percentage;

    /* Check if battery is plugged in */
    battery_present = power_status->battery_present = acpistate.present;

    /* Get temperature and fan status */
    power_status->fan_status=get_fan_status();
    get_temperature(&(power_status->temperature), &(power_status->temp_is_celsius));

    if (fast_charge_mode && (power_status->battery_percentage == 100)) fast_battery_charge(0);

		/* Let's see wether we failed to get battery time */
		if (battery_present && (battery_percentage < 100) && (power_status->battery_time <= 0))
		{
			/* OK, we failed, we calculate the value ourselves */
			power_status->battery_time = calculate_battery_time(battery_percentage, ac_on_line);
		}

    return;
  }

  /* Is this an APM system? */
  if (pm_type == PM_APM)
  {
    struct_apm_data apm_data;

    if (!apm_read(&apm_data))
    {
      fprintf(stderr, "Could not read APM info!\n");
      return;

    }
    ac_on_line = power_status->ac_on_line = apm_data.ac_line_status;
    if ( apm_data.battery_percentage == -1)
    {
      battery_present = power_status->battery_present = 0;
      battery_percentage = power_status->battery_percentage = 0;
    }
    else
    {
      battery_present = power_status->battery_present = 1;
      power_status->battery_percentage = apm_data.battery_percentage;
      if (power_status->battery_percentage > 100) power_status->battery_percentage = 100;
      battery_percentage = power_status->battery_percentage;
    }
    if ( (int)(apm_data.battery_status) == 3)
      power_status->battery_charging=1;
    else power_status->battery_charging=0;
    power_status->battery_time = (apm_data.using_minutes) ? apm_data.battery_time : apm_data.battery_time / 60;
    power_status->fan_status=get_fan_status();
    get_temperature(&(power_status->temperature), &(power_status->temp_is_celsius));

    if (fast_charge_mode && (power_status->battery_percentage == 100)) fast_battery_charge(0);

    return;
  }
}
static gboolean
update_apm_status(t_battmon *battmon)
{
#ifdef __OpenBSD__
	struct apm_power_info apm;
#else
	struct apm_info apm;
#endif
	int charge;
	int time_remaining;
	gboolean acline;
	gchar buffer[128];

	if(battmon->method == BM_BROKEN) {
		/* See if ACPI or APM support has been enabled yet */
		if(!detect_battery_info(battmon)) return TRUE;
		if(battmon->timeoutid != 0) g_source_remove(battmon->timeoutid);
		/* Poll only once per minute if using ACPI due to a bug */
		if(battmon->method == BM_USE_ACPI) {
			battmon->timeoutid = g_timeout_add(60 * 1000, (GSourceFunc) update_apm_status, battmon);
		}
	        else {
			battmon->timeoutid = g_timeout_add(2 * 1000, (GSourceFunc) update_apm_status, battmon);
		}
	}

	/* Show initial state if using ACPI rather than waiting a minute */
	if(battmon->flag) {
		battmon->flag = FALSE;
		g_source_remove(battmon->timeoutid);
		battmon->timeoutid = g_timeout_add(60 * 1000, (GSourceFunc) update_apm_status, battmon);
	}

#ifdef __FreeBSD__
  /* This is how I read the information from the APM subsystem under
     FreeBSD.  Each time this functions is called (once every second)
     the APM device is opened, read from and then closed.
  */
  	int fd;

  	battmon->method = BM_BROKEN;
  	fd = open(APMDEVICE, O_RDONLY);
  	if (fd == -1) return TRUE;

  	if (ioctl(fd, APMIO_GETINFO, &apm) == -1)
     		return TRUE;

  	close(fd);

  	acline = apm.ai_acline ? TRUE : FALSE;
  	time_remaining = apm.ai_batt_time;
	time_remaining = time_remaining / 60; /* convert from seconds to minutes */
  	charge = apm.ai_batt_life;
#elif __OpenBSD__
  /* Code for OpenBSD by Joe Ammond <*****@*****.**>. Using the same
     procedure as for FreeBSD.
  */
  	int fd;

  	battmon->method = BM_BROKEN;
  	fd = open(APMDEVICE, O_RDONLY);
  	if (fd == -1) return TRUE;
  	if (ioctl(fd, APM_IOC_GETPOWER, &apminfo) == -1)
    		return TRUE;
  	close(fd);
  	charge = apm.battery_life;
  	time_remaining = apm.minutes_left;
  	acline = apm.ac_state ? TRUE : FALSE;
#elif __linux__
	if(battmon->method == BM_USE_ACPI) acpi_linux_read(&apm);
	else apm_read(&apm);	/* not broken and not using ACPI, assume APM */
	charge = apm.battery_percentage;
	if(battmon->method == BM_USE_ACPI) time_remaining = 0; /* no such info for ACPI :( */
	else time_remaining = apm.battery_time;
	acline = apm.ac_line_status ? TRUE : FALSE;
#endif
	
	if(charge < 0) charge = 0;
	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(battmon->battstatus), charge / 100.0);

	if(battmon->options.tooltip_display_percentage && battmon->options.tooltip_display_time) {
		if(acline) 
			g_snprintf(buffer, sizeof(buffer), _("%d%% (AC on-line)"), charge);
		else if(time_remaining > 0)
			g_snprintf(buffer, sizeof(buffer), _("%d%% (%d:%.2d) remaining"), charge, time_remaining / 60, time_remaining % 60);
		else
			g_snprintf(buffer, sizeof(buffer), _("%d%% (AC off-line)"), charge);

		add_tooltip(battmon->ebox, buffer);
	}
	else if(battmon->options.tooltip_display_percentage) {
		g_snprintf(buffer, sizeof(buffer), _("%d%%"), charge);
		add_tooltip(battmon->ebox, buffer);
	}
	else if(battmon->options.tooltip_display_time) {
		if(acline) 
			g_snprintf(buffer, sizeof(buffer), _("AC on-line"));
		else if(time_remaining > 0)
			g_snprintf(buffer, sizeof(buffer), _("%d:%.2d remaining"), time_remaining / 60, time_remaining % 60);
		else
			g_snprintf(buffer, sizeof(buffer), _("AC off-line"));

		add_tooltip(battmon->ebox, buffer);
	}
	else add_tooltip(battmon->ebox, NULL);

	if(battmon->options.display_percentage) {
		g_snprintf(buffer, sizeof(buffer), _("%d%%"), charge);
		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(battmon->battstatus), buffer);	
	}
	else gtk_progress_bar_set_text(GTK_PROGRESS_BAR(battmon->battstatus), NULL);

	if(!battmon->critical && charge <= battmon->options.critical_percentage) {
		battmon->critical = TRUE;
		battmon->low = TRUE;
		if(battmon->options.action_on_critical == BM_MESSAGE)
			xfce_warn(_("WARNING: Your battery has reached critical status. You should plug in or shutdown your computer now to avoid possible data loss."));
		if(battmon->options.action_on_critical == BM_COMMAND) {
			if(battmon->options.command_on_critical && battmon->options.command_on_critical[0])
				exec_cmd(battmon->options.command_on_critical, 0, 0);
		}
		if(battmon->options.action_on_critical == BM_COMMAND_TERM) {
			if(battmon->options.command_on_critical && battmon->options.command_on_critical[0])
				exec_cmd(battmon->options.command_on_critical, 1, 0);
		}
	}
	else if(battmon->critical && charge > battmon->options.critical_percentage)
		battmon->critical = FALSE;

	if(!battmon->low && charge <= battmon->options.low_percentage) {
		battmon->low = TRUE;
		if(battmon->options.action_on_low == BM_MESSAGE)
			xfce_warn(_("WARNING: Your battery is running low. You should consider plugging in or shutting down your computer soon to avoid possible data loss."));
		if(battmon->options.action_on_low == BM_COMMAND) {
			if(battmon->options.command_on_low && battmon->options.command_on_low[0])
				exec_cmd(battmon->options.command_on_low, 0, 0);
		}
		if(battmon->options.action_on_low == BM_COMMAND_TERM) {
			if(battmon->options.command_on_low && battmon->options.command_on_low[0])
				exec_cmd(battmon->options.command_on_low, 1, 0);
		}
	}
	else if(battmon->low && charge > battmon->options.low_percentage)
		battmon->low = FALSE;

	return TRUE;
}
gboolean
detect_battery_info(t_battmon *battmon)
{
#ifdef __OpenBSD__
	struct apm_power_info apm;
#else
	struct apm_info apm;
#endif

#ifdef __FreeBSD__
  /* This is how I read the information from the APM subsystem under
     FreeBSD.  Each time this functions is called (once every second)
     the APM device is opened, read from and then closed.
  */
  	int fd;

	battmon->method = BM_BROKEN;
  	fd = open(APMDEVICE, O_RDONLY);
  	if (fd == -1) return FALSE;

  	if (ioctl(fd, APMIO_GETINFO, &apm) == -1)
     		return FALSE;

  	close(fd);
  	battmon->method = BM_USE_APM;

  	return TRUE;
#elif __OpenBSD__
  /* Code for OpenBSD by Joe Ammond <*****@*****.**>. Using the same
     procedure as for FreeBSD.
  */
  	int fd;

  	battmon->method = BM_BROKEN;
  	fd = open(APMDEVICE, O_RDONLY);
  	if (fd == -1) return FALSE;
  	if (ioctl(fd, APM_IOC_GETPOWER, &apm) == -1)
    		return FALSE;
  	close(fd);
  	battmon->method = BM_USE_APM;
  
  	return TRUE;
#elif __linux__
	/* First check to see if ACPI is available */
	if(acpi_linux_read(&apm)) {
		/* ACPI detected and working */
		battmon->method = BM_USE_ACPI;
		return TRUE;
	}
	if(apm_read(&apm) == 0) {
		/* ACPI not detected, but APM works */
		battmon->method = BM_USE_APM;
		return TRUE;
	}

	/* Neither ACPI or APM detected/working */
	battmon->method = BM_BROKEN;

	return FALSE;
#endif	
}
Beispiel #10
0
void main_loop (void) {
	int activity=0, sleep_now=0, total_unused=0;
	int sleep_battery=0;
	int prev_ac_line_status=0;
	time_t nowtime, oldtime=0;
	apm_info ai;
	double loadavg[1];

	if (use_events) {
		pthread_t emthread;
		pthread_create(&emthread, NULL, eventMonitor, NULL);
	}

	while (1) {
		activity=0;
		if (use_events) {
			pthread_mutex_lock(&condition_mutex);
			pthread_cond_signal(&condition_cond);
			pthread_mutex_unlock(&condition_mutex);
		}

		if (use_acpi) {
			acpi_read(1, &ai);
		}
#ifdef HAL
		else if (use_simplehal) {
			simplehal_read(1, &ai);
		}
#endif
		else {
			apm_read(&ai);
		}

		if (min_batt != -1 && ai.ac_line_status != 1 && 
		    ai.battery_percentage < min_batt &&
		    ai.battery_status != BATTERY_STATUS_ABSENT) {
			sleep_battery = 1;
		}
		if (sleep_battery && ! require_unused_and_battery) {
			syslog(LOG_NOTICE, "battery level %d%% is below %d%%; forcing hibernation", ai.battery_percentage, min_batt);
			if (system(hibernate_command) != 0)
				syslog(LOG_ERR, "%s failed", hibernate_command);
			/* This counts as activity; to prevent double sleeps. */
			if (debug)
				printf("sleepd: activity: just woke up\n");
			activity=1;
			oldtime=0;
			sleep_battery=0;
		}
	
		/* Rest is only needed if sleeping on inactivity. */
		if (! max_unused && ! ac_max_unused) {
			sleep(sleep_time);
			continue;
		}

		if (autoprobe || have_irqs) {
			activity=check_irqs(activity, autoprobe);
		}

		if (use_net) {
			activity=check_net(activity);
		}

		if ((max_loadavg != 0) &&
		    (getloadavg(loadavg, 1) == 1) &&
		    (loadavg[0] >= max_loadavg)) {
			/* If the load average is too high */
			if (debug)
				printf("sleepd: activity: load average %f\n", loadavg[0]);
			activity=1;
		}

		if (use_utmp == 1) {
			total_unused=check_utmp(total_unused);
		}

		if (ai.ac_line_status != prev_ac_line_status) {
			/* AC plug/unplug counts as activity. */
			if (debug)
				printf("sleepd: activity: AC status change\n");
			activity=1;
		}
		prev_ac_line_status=ai.ac_line_status;

		sleep(sleep_time);

		if (use_events) {
			pthread_mutex_lock(&activity_mutex);
			if (eventData.emactivity == 1) {
				if (debug)
					printf("sleepd: activity: keyboard/mouse events\n");
				activity=1;
			}
			pthread_mutex_unlock(&activity_mutex);
		}

		if (activity) {
			total_unused = 0;
		}
		else {
			total_unused += sleep_time;
			if (ai.ac_line_status == 1) {
				/* On wall power. */
				if (ac_max_unused > 0) {
					sleep_now = total_unused >= ac_max_unused;
				}
			}
			else if (max_unused > 0) {
				sleep_now = total_unused >= max_unused;
			}

			if (sleep_now && ! no_sleep && ! require_unused_and_battery) {
				syslog(LOG_NOTICE, "system inactive for %ds; forcing sleep", total_unused);
				if (system(sleep_command) != 0)
					syslog(LOG_ERR, "%s failed", sleep_command);
				total_unused=0;
				oldtime=0;
				sleep_now=0;
			}
			else if (sleep_now && ! no_sleep && sleep_battery) {
				syslog(LOG_NOTICE, "system inactive for %ds and battery level %d%% is below %d%%; forcing hibernaton", 
				       total_unused, ai.battery_percentage, min_batt);
				if (system(hibernate_command) != 0)
					syslog(LOG_ERR, "%s failed", hibernate_command);
				total_unused=0;
				oldtime=0;
				sleep_now=0;
				sleep_battery=0;
			}
		}
		
		/*
		 * Keep track of how long it's been since we were last
		 * here. If it was much longer than sleep_time, the system
		 * was probably suspended, or this program was, (or the 
		 * kernel is thrashing :-), so clear idle counter.
		 */
		nowtime=time(NULL);
		/* The 1 is a necessary fudge factor. */
		if (oldtime && nowtime - sleep_time > oldtime + 1) {
			no_sleep=0; /* reset, since they must have put it to sleep */
			writecontrol(no_sleep);
			syslog(LOG_NOTICE,
					"%i sec sleep; resetting timer",
					(int)(nowtime - oldtime));
			total_unused=0;
		}
		oldtime=nowtime;
	}
}