fordon_greeman / sfetch

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