i3 - improved tiling WM


Add file_contents module to print arbitrary file data.

Patch status: superseded

Patch by Luke Heberling

Long description:

This can be used to replace external wrapper scripts with single-purpose
scripts, easily distributable in contrib.

To apply this patch, use:
curl http://cr.i3wm.org/patch/627/raw.patch | git am

b/i3status.c

19
@@ -402,6 +402,12 @@ int main(int argc, char *argv[]) {
20
                 CFG_END()
21
         };
22
 
23
+        cfg_opt_t file_contents_opts[] = {
24
+                CFG_STR("file", NULL, CFGF_NONE),
25
+                CFG_CUSTOM_COLOR_OPTS,
26
+                CFG_END()
27
+        };
28
+
29
         cfg_opt_t opts[] = {
30
                 CFG_STR_LIST("order", "{}", CFGF_NONE),
31
                 CFG_SEC("general", general_opts, CFGF_NONE),
32
@@ -419,6 +425,7 @@ int main(int argc, char *argv[]) {
33
                 CFG_SEC("ddate", ddate_opts, CFGF_NONE),
34
                 CFG_SEC("load", load_opts, CFGF_NONE),
35
                 CFG_SEC("cpu_usage", usage_opts, CFGF_NONE),
36
+                CFG_SEC("file_contents", file_contents_opts, CFGF_TITLE | CFGF_MULTI),
37
                 CFG_END()
38
         };
39
 
40
@@ -652,6 +659,12 @@ int main(int argc, char *argv[]) {
41
                                 print_cpu_usage(json_gen, buffer, cfg_getstr(sec, "format"));
42
                                 SEC_CLOSE_MAP;
43
                         }
44
+
45
+                        CASE_SEC_TITLE("file_contents") {
46
+                                SEC_OPEN_MAP("file_contents");
47
+                                print_file_contents(json_gen, buffer, title, cfg_getstr(sec, "file"));
48
+                                SEC_CLOSE_MAP;
49
+                        }
50
                 }
51
                 if (output_format == O_I3BAR) {
52
                         yajl_gen_array_close(json_gen);

b/include/i3status.h

57
@@ -184,6 +184,7 @@ void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format);
58
 void print_eth_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down);
59
 void print_load(yajl_gen json_gen, char *buffer, const char *format, const float max_threshold);
60
 void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *fmt_muted, const char *device, const char *mixer, int mixer_idx);
61
+void print_file_contents(yajl_gen json_gen, char *buffer, const char *title, const char *file);
62
 bool process_runs(const char *path);
63
 
64
 /* socket file descriptor for general purposes */

b/man/i3status.man

69
@@ -47,6 +47,7 @@ general {
70
         interval = 5
71
 }
72
 
73
+order += "file_contents motd"
74
 order += "ipv6"
75
 order += "disk /"
76
 order += "run_watch DHCP"
77
@@ -60,6 +61,10 @@ order += "load"
78
 order += "tztime local"
79
 order += "tztime berlin"
80
 
81
+file_contents motd {
82
+	path = "/etc/motd"
83
+}
84
+
85
 wireless wlan0 {
86
         format_up = "W: (%quality at %essid, %bitrate) %ip"
87
         format_down = "W: down"
88
@@ -196,6 +201,11 @@ disk "/" {
89
 }
90
 -------------------------------------------------------------
91
 
92
+=== File Contents
93
+This module gets the first line of a file, up to 128 characters.
94
+
95
+*Example path*: +/etc/motd+
96
+
97
 === IPv6
98
 
99
 This module gets the IPv6 address used for outgoing connections (that is, the

b/src/print_file_contents.c

105
@@ -0,0 +1,30 @@
106
+#include <stdio.h>
107
+#include <string.h>
108
+#include <glob.h>
109
+#include <yajl/yajl_gen.h>
110
+#include <yajl/yajl_version.h>
111
+#include "i3status.h"
112
+
113
+void print_file_contents(yajl_gen json_gen, char *buffer, const char *title, const char *file) {
114
+	char *outwalk = buffer;
115
+
116
+	INSTANCE(title);
117
+
118
+	static glob_t globbuf;
119
+
120
+	if (glob(file, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0)
121
+		die("glob() failed\n");
122
+	// We can't access actual size of buffer here, but it's 4096 currently
123
+	if (!slurp((globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : file), outwalk, 128))
124
+		*outwalk = '\0';
125
+	// slurp zero-terminates the buffer
126
+
127
+	globfree(&globbuf);
128
+	char *eol = strchr(outwalk, '\n');
129
+	if (eol != NULL) {
130
+		outwalk = eol;
131
+	} else {
132
+		outwalk = strchr(outwalk, '\0');
133
+	}
134
+	OUTPUT_FULL_TEXT(buffer);
135
+}