fordon_greeman / sfetch

Branch: aa85f24
Switch branches/tags
main
theidioticdev forgot to add acooliodude's overlay instructions aa85f24 1d ago
292 lines · 6.2 KB Raw Blame History
1 /* the unsuckless update */
2 #include <stdio.h>
3 #include <sys/utsname.h>
4 #include <sys/stat.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <libgen.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10
11 #define C_RESET "\033[0m"
12 #define C_BOLD "\033[1m"
13 #define C_ORANGE "\033[38;5;208m"
14 #define C_BLUE "\033[1;34m"
15 #define C_YELLOW "\033[1;33m"
16 #define C_CYAN "\033[1;36m"
17 #define C_GREEN "\033[1;32m"
18 #define C_RED "\033[1;31m"
19 #define C_PURPLE "\033[1;35m"
20
21 const char *version = "0.1.7";
22
23 typedef struct {
24 int ascii;
25 int quote;
26 int krn_mod;
27 int os_mod;
28 int sh_mod;
29 int wm_mod;
30 int hn_mod;
31 int term_mod;
32 int mem_mod;
33 } Config;
34
35 Config config = {
36 .ascii = 1,
37 .quote = 1,
38 .os_mod = 1,
39 .sh_mod = 1,
40 .krn_mod = 1,
41 .wm_mod = 1,
42 .hn_mod = 1,
43 .term_mod = 1,
44 .mem_mod = 1,
45 };
46
47 int
48 config_parse (const char *fp)
49 {
50 FILE *f = fopen (fp, "r");
51 if (!f)
52 {
53 return -1;
54 }
55 char line[1024];
56
57 while (fgets(line, sizeof(line), f))
58 {
59 char key[64], val[512];
60 /* boilerplate... */
61 if (sscanf (line, " %63[^ =] = %511s", key, val) == 2)
62 {
63 if (strcmp(key, "ascii") == 0)
64 {
65 config.ascii = (strcmp(val, "true") == 0);
66 }
67 else if (strcmp(key, "quote") == 0)
68 {
69 config.quote = (strcmp(val, "true") == 0);
70 }
71 else if (strcmp(key, "os_mod") == 0)
72 {
73 config.os_mod = (strcmp(val, "true") == 0);
74 }
75 else if (strcmp(key, "sh_mod") == 0)
76 {
77 config.sh_mod = (strcmp(val, "true") == 0);
78 }
79 else if (strcmp(key, "krn_mod") == 0)
80 {
81 config.krn_mod = (strcmp(val, "true") == 0);
82 }
83 else if (strcmp(key, "wm_mod") == 0)
84 {
85 config.wm_mod = (strcmp(val, "true") == 0);
86 }
87 else if (strcmp(key, "hn_mod") == 0)
88 {
89 config.hn_mod = (strcmp(val, "true") == 0);
90 }
91 else if (strcmp(key, "term_mod") == 0)
92 {
93 config.term_mod = (strcmp(val, "true") == 0);
94 }
95 else if (strcmp(key, "mem_mod") == 0)
96 {
97 config.mem_mod = (strcmp(val, "true") == 0);
98 }
99 }
100 }
101 fclose(f);
102 return 0;
103 }
104
105 void
106 print_text (void)
107 {
108 if (!config.quote)
109 return;
110 printf ("\n " C_PURPLE "\"the quick fox jumps somewhere, idk.\"\n\n" C_RESET);
111 }
112
113 void
114 print_ascii (const char *ascii_file)
115 {
116 if (!config.ascii)
117 return;
118 FILE *f = fopen(ascii_file, "r");
119 if (!f)
120 {
121 printf (C_GREEN "No Ascii :(" C_RESET "\n\n");
122 return;
123 }
124 char buf[2048];
125 size_t len = fread (buf, 1, sizeof (buf) - 1, f);
126 buf[len] = '\0';
127 fclose (f);
128
129 printf (C_GREEN "%s" C_RESET "\n\n", buf);
130 }
131
132 /* generic way of getting ram, sadly sysinfo sucks ass */
133 void
134 get_mem (unsigned long *total, unsigned long *avail)
135 {
136 FILE *fp = fopen ("/proc/meminfo", "r");
137 if (!fp)
138 return;
139 char line[255];
140 while (fgets (line, sizeof (line), fp))
141 {
142 if (strncmp (line, "MemTotal:", 9) == 0)
143 sscanf (line + 9, "%lu", total);
144 else if (strncmp (line, "MemAvailable:", 13) == 0)
145 sscanf (line + 13, "%lu", avail);
146
147 if (*total && *avail)
148 break;
149 }
150 fclose (fp);
151 }
152
153 /* ty "bugs in nixmania" on tonybtw discord */
154 void
155 print_os (void)
156 {
157 #ifdef __linux__
158 FILE *fp = fopen ("/etc/os-release", "r");
159 if (fp)
160 {
161 static const char key[] = "PRETTY_NAME=";
162 const size_t klen = sizeof key - 1;
163 char buf[256];
164 while (fgets (buf, sizeof buf, fp))
165 {
166 if (strncmp (buf, key, klen) != 0)
167 continue;
168 buf[strcspn (buf, "\n")] = '\0';
169 char *val = buf + klen;
170 size_t len = strlen (val);
171 if (len >= 2 && (val[0] == '"' || val[0] == '\'') &&
172 val[len - 1] == val[0])
173 {
174 val[len - 1] = '\0';
175 val++;
176 }
177 printf (C_CYAN "OS: " C_RESET "%s\n", val);
178 fclose (fp);
179 return;
180 }
181 fclose (fp);
182 }
183 printf (C_CYAN "OS: " C_RESET "Generic Linux\n");
184 #else
185 struct utsname other_os;
186 if (uname (&other_os) != 0)
187 {
188 perror ("uname");
189 return;
190 }
191 printf (C_CYAN "OS: " C_RESET "%s\n", other_os.sysname);
192 #endif
193 }
194
195 int
196 print_stats (void)
197 {
198 /* preparing stats */
199 char *shell = getenv ("SHELL");
200
201 char *term = getenv ("TERM_PROGRAM");
202 if (!term)
203 {
204 term = getenv ("TERM");
205 }
206
207 char *wm = getenv ("XDG_CURRENT_DESKTOP");
208 if (!wm)
209 {
210 wm = getenv ("DESKTOP_SESSION");
211 }
212
213 struct utsname info;
214 if (uname (&info) != 0)
215 {
216 perror ("uname");
217 return 1;
218 }
219
220 /* actual printing guarded by config toggles */
221 if (config.os_mod)
222 {
223 print_os ();
224 }
225
226 if (config.sh_mod && shell)
227 {
228 printf (C_RED "Shell: " C_RESET "%s\n", basename (shell));
229 }
230
231 if (config.krn_mod)
232 {
233 printf (C_ORANGE "Kernel: " C_RESET "%s %s\n", info.sysname, info.release);
234 }
235
236 if (config.wm_mod)
237 {
238 printf (C_YELLOW "WM: " C_RESET "%s\n", wm ? wm : "unknown/tty");
239 }
240
241 if (config.hn_mod)
242 {
243 printf (C_GREEN "Host: " C_RESET "%s\n", info.nodename);
244 }
245
246 if (config.term_mod)
247 {
248 printf (C_BLUE "Term: " C_RESET "%s\n", term ? term : "unknown");
249 }
250
251 if (config.mem_mod)
252 {
253 unsigned long total_kb = 0, avail_kb = 0;
254 get_mem (&total_kb, &avail_kb);
255
256 if (total_kb > 0)
257 {
258 unsigned long used_mb = (total_kb - avail_kb) / 1024;
259 unsigned long total_mb = total_kb / 1024;
260 printf (C_PURPLE "Mem: " C_RESET "%luMiB / %luMiB\n", used_mb, total_mb);
261 }
262 }
263
264 return 0;
265 }
266
267 int
268 main()
269 {
270 char *xdg = getenv("XDG_CONFIG_HOME");
271 char config_dir[256];
272
273 if (xdg == NULL || xdg[0] == '\0') {
274 snprintf(config_dir, sizeof(config_dir), "%s/.config", getenv("HOME"));
275 } else {
276 snprintf(config_dir, sizeof(config_dir), "%s", xdg);
277 }
278
279 char file_path[512];
280 snprintf(file_path, sizeof(file_path), "%s/sfetch/sfetch.conf", config_dir);
281
282 config_parse(file_path);
283
284 print_text();
285
286 snprintf(file_path, sizeof(file_path), "%s/sfetch/ascii.txt", config_dir);
287 print_ascii(file_path);
288
289 print_stats();
290
291 return 0;
292 }