]> gitweb.michael.orlitzky.com - xfce4-hdaps.git/blob - panel-plugin/hdaps.c
cb5e459c7f20b672e8dabac9d63329bf2454ad27
[xfce4-hdaps.git] / panel-plugin / hdaps.c
1 /*
2 * xfce4-hdaps, an XFCE4 panel plugin for the HDAPS system.
3 *
4 * Copyright Michael Orlitzky
5 *
6 * http://michael.orlitzky.com/
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * http://www.fsf.org/licensing/licenses/gpl.html
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <dirent.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include "hdaps.h"
32
33 /* The most space we expect to need when reading in
34 a file using these hdaps functions. To exceed 32
35 bytes worth of content in unload_heads you'd have
36 to throw your laptop hard as a motherfucker. */
37 #define MAX_FILE_CONTENTS_SIZE 32
38
39 /* Where the block device names are located. */
40 #define SYSFS_BLOCK_DEVICE_DIR "/sys/block/"
41
42
43
44 static int hdaps_device_exists(const char* device) {
45 /* Determine whether or not a device (file) exists and has an
46 unload_heads entry in sysfs. */
47 char path[FILENAME_MAX];
48 snprintf(path, FILENAME_MAX, UNLOAD_HEADS_FMT, device);
49 return (access(path, F_OK) == 0);
50 }
51
52
53
54 int get_hdaps_device_list(char list[MAX_HDAPS_DEVICES][FILENAME_MAX]) {
55 /* Gets a list of devices which support HDAPS.
56 * We start by getting every device in the sysfs
57 * block device directory, and then eliminate those
58 * which don't have an unload_heads entry.
59 */
60 int list_idx = 0;
61 DIR *dp;
62 struct dirent *ep;
63
64 dp = opendir(SYSFS_BLOCK_DEVICE_DIR);
65
66 if (dp != NULL) {
67 while ((ep = readdir(dp)) && list_idx < MAX_HDAPS_DEVICES) {
68 /* This next test covers "." and ".." too. */
69 if (hdaps_device_exists(ep->d_name)) {
70 strncpy(list[list_idx], ep->d_name, FILENAME_MAX);
71 list_idx++;
72 }
73 }
74
75 (void)closedir(dp); /* Explicitly ignore this. */
76 }
77
78 return list_idx;
79 }
80
81
82
83 int slurp_file(const char* filename, char* buf, int max_bytes) {
84 /* This function just reads the contents of filename
85 * into buf, and returns the number of bytes read.
86 */
87 if (filename == NULL || buf == NULL) {
88 /* HDAPS_SUPER_BAD_ERROR */
89 return HDAPS_ERROR;
90 }
91
92
93 /* Return an error value by default. */
94 int bytes_read = HDAPS_ERROR;
95
96 int fd = open(filename, O_RDONLY);
97
98 if (fd < 0) {
99 /* open() didn't work. Report the error, and bail. */
100 fprintf(stderr, "open(%s): %s\n", filename, strerror(errno));
101 return HDAPS_ERROR;
102 }
103
104 bytes_read = read(fd, buf, max_bytes-1);
105
106 if (bytes_read < 0) {
107 /* Why did we read fewer than 0 bytes? */
108 fprintf(stderr, "read(%s): %s\n", filename, strerror(errno));
109 }
110 else {
111 /* Null-terminate buf if read() worked. */
112 buf[bytes_read] = 0;
113 }
114
115
116 if (close(fd)) {
117 /* Oh hey we should be able to close the file, too. */
118 fprintf(stderr, "close(%s): %s\n", filename, strerror(errno));
119 }
120
121 return bytes_read;
122 }
123
124
125
126
127 int parse_int_from_file(const char* filename) {
128 /* Read an integer from a file. We expect the file
129 to contain an integer (although in string form). */
130
131 char buf[MAX_FILE_CONTENTS_SIZE];
132 int bytes_read = slurp_file(filename, buf, sizeof(buf));
133
134 if (bytes_read <= 0) {
135 /* We can't parse what doesn't exist. Note that
136 * reading "0" from a file should result in reading
137 * at least 1 byte.
138 */
139 return HDAPS_ERROR;
140 }
141 else {
142 /* If we read more than 0 bytes, hopefully we can
143 * count on atoi to succeed. */
144 return atoi(buf);
145 }
146 }