]> git.sur5r.net Git - i3/i3status/blob - src/output.c
Bugfix: close the filehandle when done
[i3/i3status] / src / output.c
1 // vim:ts=8:expandtab
2 #include <stdbool.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <fcntl.h>
9 #include <dirent.h>
10
11 #include "i3status.h"
12
13 /*
14  * Writes an errormessage to statusbar
15  *
16  */
17 void write_error_to_statusbar(const char *message) {
18         cleanup_rbar_dir();
19         create_file("error");
20         write_to_statusbar("error", message, true);
21 }
22
23 /*
24  * Returns the correct color format for dzen (^fg(color)) or wmii (color <normcolors>)
25  *
26  */
27 char *color(const char *colorstr) {
28         static char colorbuf[32];
29         if (!use_colors) {
30                 colorbuf[0] = '\0';
31                 return colorbuf;
32         }
33 #ifdef DZEN
34         (void)snprintf(colorbuf, sizeof(colorbuf), "^fg(%s)", colorstr);
35 #elif XMOBAR
36         (void)snprintf(colorbuf, sizeof(colorbuf), "<fc=%s>", colorstr);
37 #else
38         (void)snprintf(colorbuf, sizeof(colorbuf), "%s %s ", colorstr, wmii_normcolors);
39 #endif
40         return colorbuf;
41 }
42
43 /*
44  * Some color formats (xmobar) require to terminate colors again
45  *
46  */
47 char *endcolor() {
48 #ifdef XMOBAR
49         return "</fc>";
50 #else
51         return "";
52 #endif
53 }
54
55 /*
56  * Cleans wmii's /rbar directory by deleting all regular files
57  *
58  */
59 void cleanup_rbar_dir() {
60 #if defined(DZEN) || defined(XMOBAR)
61         return;
62 #endif
63         struct dirent *ent;
64         DIR *dir;
65         char pathbuf[strlen(wmii_path)+256+1];
66
67         if ((dir = opendir(wmii_path)) == NULL)
68                 exit(EXIT_FAILURE);
69
70         while ((ent = readdir(dir)) != NULL) {
71                 if (ent->d_type == DT_REG) {
72                         (void)snprintf(pathbuf, sizeof(pathbuf), "%s%s", wmii_path, ent->d_name);
73                         if (unlink(pathbuf) == -1)
74                                 exit(EXIT_FAILURE);
75                 }
76         }
77
78         (void)closedir(dir);
79 }
80
81 /*
82  * Creates the specified file in wmii's /rbar directory with
83  * correct modes and initializes colors if colormode is enabled
84  *
85  */
86 void create_file(const char *name) {
87 #if defined(DZEN) || defined(XMOBAR)
88         return;
89 #endif
90         char pathbuf[strlen(wmii_path)+256+1];
91         int fd;
92         int flags = O_CREAT | O_WRONLY;
93         struct stat statbuf;
94
95         (void)snprintf(pathbuf, sizeof(pathbuf), "%s%s", wmii_path, name);
96
97         /* Overwrite file's contents if it exists */
98         if (stat(pathbuf, &statbuf) >= 0)
99                 flags |= O_TRUNC;
100
101         if ((fd = open(pathbuf, flags, S_IRUSR | S_IWUSR)) < 0)
102                 exit(EXIT_FAILURE);
103         if (use_colors) {
104                 char *tmp = color("#888888");
105                 if (write(fd, tmp, strlen(tmp)) != (ssize_t)strlen(tmp))
106                         exit(EXIT_FAILURE);
107         }
108         (void)close(fd);
109 }
110
111 /*
112  * Waits until wmii_path/rbar exists (= the filesystem gets mounted),
113  * cleans up all files and creates the needed files
114  *
115  */
116 void setup(void) {
117         unsigned int i;
118         char pathbuf[512];
119
120 #if !defined(DZEN) && !defined(XMOBAR)
121         struct stat statbuf;
122         /* Wait until wmii_path/rbar exists */
123         for (; stat(wmii_path, &statbuf) < 0; sleep(interval));
124 #endif
125 #define cf(orderidx, name) create_file(order_to_str(order[orderidx], name));
126
127         cleanup_rbar_dir();
128         if (wlan_interface)
129                 cf(ORDER_WLAN, "wlan");
130         if (eth_interface)
131                 cf(ORDER_ETH, "eth");
132         if (get_cpu_temperature)
133                 cf(ORDER_CPU_TEMPERATURE, "cpu_temperature");
134         cf(ORDER_LOAD, "load");
135         if (time_format)
136                 cf(ORDER_TIME, "time");
137         for (i = 0; i < num_run_watches; i += 2) {
138                 snprintf(pathbuf, sizeof(pathbuf), "%d%s", order[ORDER_RUN], run_watches[i]);
139                 create_file(pathbuf);
140         }
141 }
142
143 /*
144  * Writes the given message in the corresponding file in wmii's /rbar directory
145  *
146  */
147 void write_to_statusbar(const char *name, const char *message, bool final_entry) {
148 #ifdef DZEN
149         if (final_entry) {
150                 if (printf("%s^p(6)\n", message) < 0) {
151                         perror("printf");
152                         exit(1);
153                 }
154
155                 fflush(stdout);
156                 return;
157         }
158         if (printf("%s" BAR, message) < 0) {
159                 perror("printf");
160                 exit(1);
161         }
162         return;
163 #elif XMOBAR
164         if (final_entry) {
165                 if (printf("%s\n", message) < 0) {
166                         perror("printf");
167                         exit(1);
168                 }
169
170                 fflush(stdout);
171                 return;
172         }
173         if (printf("%s" BAR, message) < 0) {
174                 perror("printf");
175                 exit(1);
176         }
177         return;
178
179 #endif
180
181         char pathbuf[strlen(wmii_path)+256+1];
182         int fd;
183
184         (void)snprintf(pathbuf, sizeof(pathbuf), "%s%s", wmii_path, name);
185         if ((fd = open(pathbuf, O_RDWR)) == -1) {
186                 /* Try to re-setup stuff and just continue */
187                 setup();
188                 return;
189         }
190         if (write(fd, message, strlen(message)) != (ssize_t)strlen(message))
191                 exit(EXIT_FAILURE);
192         (void)close(fd);
193 }