1 /*
2  *
3  * Conky, a system monitor, based on torsmo
4  *
5  * Any original torsmo code is licensed under the BSD license
6  *
7  * All code written since the fork of torsmo is licensed under the GPL
8  *
9  * Please see COPYING for details
10  *
11  * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al.
12  *	(see AUTHORS)
13  * All rights reserved.
14  *
15  * This program is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  * You should have received a copy of the GNU General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 
29 #include <getopt.h>
30 #include <cstdio>
31 #include <iostream>
32 
33 #include "build.h"
34 #include "config.h"
35 #include "conky.h"
36 #include "lua-config.hh"
37 
38 #ifdef BUILD_X11
39 #include "x11.h"
40 #endif /* BUILD_X11 */
41 
42 #ifdef BUILD_CURL
43 #include "ccurl_thread.h"
44 #endif /* BUILD_CURL */
45 
46 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
47 #include "freebsd.h"
48 #endif /* FreeBSD */
49 
50 #ifdef BUILD_BUILTIN_CONFIG
51 #include "defconfig.h"
52 
53 #ifdef BUILD_OLD_CONFIG
54 #include "convertconf.h"
55 #endif /* BUILD_OLD_CONFIG */
56 #endif /* BUILD_BUILTIN_CONFIG */
57 
print_version()58 static void print_version() {
59   std::cout << _(PACKAGE_NAME " " VERSION " compiled " BUILD_DATE
60                               " for " BUILD_ARCH
61                               "\n"
62                               "\nCompiled in features:\n\n"
63                               "System config file: " SYSTEM_CONFIG_FILE
64                               "\n"
65                               "Package library path: " PACKAGE_LIBDIR "\n\n")
66             << _("\n General:\n")
67 #ifdef HAVE_OPENMP
68             << _("  * OpenMP\n")
69 #endif /* HAVE_OPENMP */
70 #ifdef BUILD_MATH
71             << _("  * math\n")
72 #endif /* BUILD_MATH */
73 #ifdef BUILD_HDDTEMP
74             << _("  * hddtemp\n")
75 #endif /* BUILD_HDDTEMP */
76 #ifdef BUILD_PORT_MONITORS
77             << _("  * portmon\n")
78 #endif /* BUILD_PORT_MONITORS */
79 #ifdef BUILD_HTTP
80             << _("  * HTTP\n")
81 #endif /* BUILD_HTTP */
82 #ifdef BUILD_IPV6
83             << _("  * IPv6\n")
84 #endif /* BUILD_IPV6 */
85 #ifdef BUILD_IRC
86             << _("  * IRC\n")
87 #endif
88 #ifdef BUILD_CURL
89             << _("  * Curl\n")
90 #endif /* BUILD_CURL */
91 #ifdef BUILD_RSS
92             << _("  * RSS\n")
93 #endif /* BUILD_RSS */
94 #ifdef BUILD_ICAL
95             << _("  * ICal\n")
96 #endif /* BUILD_ICAL */
97 #ifdef BUILD_ICONV
98             << _("  * iconv\n")
99 #endif /* BUILD_ICONV */
100 #ifdef BUILD_MYSQL
101             << _("  * MySQL\n")
102 #endif /* BUILD_MYSQL */
103 #ifdef BUILD_WEATHER_METAR
104             << _("  * Weather (METAR)\n")
105 #endif /* BUILD_WEATHER_METAR */
106 #ifdef BUILD_WLAN
107             << _("  * wireless\n")
108 #endif /* BUILD_WLAN */
109 #ifdef BUILD_IBM
110             << _("  * support for IBM/Lenovo notebooks\n")
111 #endif /* BUILD_IBM */
112 #ifdef BUILD_NVIDIA
113             << _("  * nvidia\n")
114 #endif /* BUILD_NVIDIA */
115 #ifdef BUILD_BUILTIN_CONFIG
116             << _("  * builtin default configuration\n")
117 #endif /* BUILD_BUILTIN_CONFIG */
118 #ifdef BUILD_OLD_CONFIG
119             << _("  * old configuration syntax\n")
120 #endif /* BUILD_OLD_CONFIG */
121 #ifdef BUILD_IMLIB2
122             << _("  * Imlib2\n")
123 #endif /* BUILD_IMLIB2 */
124 #ifdef HAVE_SOME_SOUNDCARD_H
125             << _("  * OSS mixer support\n")
126 #endif /* HAVE_SOME_SOUNDCARD_H */
127 #ifdef BUILD_MIXER_ALSA
128             << _("  * ALSA mixer support\n")
129 #endif /* BUILD_MIXER_ALSA */
130 #ifdef BUILD_APCUPSD
131             << _("  * apcupsd\n")
132 #endif /* BUILD_APCUPSD */
133 #ifdef BUILD_IOSTATS
134             << _("  * iostats\n")
135 #endif /* BUILD_IOSTATS */
136 #ifdef BUILD_NCURSES
137             << _("  * ncurses\n")
138 #endif /* BUILD_NCURSES */
139 #ifdef BUILD_I18N
140             << _("  * Internationalization support\n")
141 #endif
142 #ifdef BUILD_PULSEAUDIO
143             << _("  * PulseAudio\n")
144 #endif /* BUIL_PULSEAUDIO */
145 #ifdef DEBUG
146             << _("  * Debugging extensions\n")
147 #endif
148 #if defined BUILD_LUA_CAIRO || defined BUILD_LUA_IMLIB2 || BUILD_LUA_RSVG
149             << _("\n Lua bindings:\n")
150 #endif
151 #ifdef BUILD_LUA_CAIRO
152             << _("  * Cairo\n")
153 #endif /* BUILD_LUA_CAIRO */
154 #ifdef BUILD_LUA_IMLIB2
155             << _("  * Imlib2\n")
156 #endif /* BUILD_LUA_IMLIB2 */
157 #ifdef BUILD_LUA_RSVG
158             << _("  * RSVG\n")
159 #endif /* BUILD_LUA_RSVG */
160 #ifdef BUILD_X11
161             << _(" X11:\n")
162 #ifdef BUILD_XDAMAGE
163             << _("  * Xdamage extension\n")
164 #endif /* BUILD_XDAMAGE */
165 #ifdef BUILD_XINERAMA
166             << _("  * Xinerama extension (virtual display)\n")
167 #endif /* BUILD_XINERAMA */
168 #ifdef BUILD_XSHAPE
169             << _("  * Xshape extension (click through)\n")
170 #endif /* BUILD_XSHAPE */
171 #ifdef BUILD_XDBE
172             << _("  * XDBE (double buffer extension)\n")
173 #endif /* BUILD_XDBE */
174 #ifdef BUILD_XFT
175             << _("  * Xft\n")
176 #endif /* BUILD_XFT */
177 #ifdef BUILD_ARGB
178             << _("  * ARGB visual\n")
179 #endif /* BUILD_ARGB */
180 #ifdef OWN_WINDOW
181             << _("  * Own window\n")
182 #endif
183 #endif /* BUILD_X11 */
184 #ifdef BUILD_HSV_GRADIENT
185             << _("  * HSV Gradient\n")
186 #endif /* BUILD_HSV_GRADIENT */
187 #if defined BUILD_AUDACIOUS || defined BUILD_CMUS || defined BUILD_MPD || \
188     defined BUILD_MOC || defined BUILD_XMMS2
189             << _("\n Music detection:\n")
190 #endif
191 #ifdef BUILD_AUDACIOUS
192             << _("  * Audacious\n")
193 #endif /* BUILD_AUDACIOUS */
194 #ifdef BUILD_CMUS
195             << _("  * CMUS\n")
196 #endif /* BUILD_CMUS */
197 #ifdef BUILD_MPD
198             << _("  * MPD\n")
199 #endif /* BUILD_MPD */
200 #ifdef BUILD_MOC
201             << _("  * MOC\n")
202 #endif /* BUILD_MOC */
203 #ifdef BUILD_XMMS2
204             << _("  * XMMS2\n")
205 #endif /* BUILD_XMMS2 */
206             << _("\n Default values:\n") << "  * Netdevice: " DEFAULTNETDEV "\n"
207             << "  * Local configfile: " CONFIG_FILE "\n"
208 #ifdef BUILD_I18N
209             << "  * Localedir: " LOCALE_DIR "\n"
210 #endif /* BUILD_I18N */
211 #ifdef BUILD_HTTP
212             << "  * HTTP-port: " << HTTPPORT << "\n"
213 #endif /* BUILD_HTTP */
214             << "  * Maximum netdevices: " << MAX_NET_INTERFACES << "\n"
215             << "  * Maximum text size: " << MAX_USER_TEXT_DEFAULT << "\n"
216             << "  * Size text buffer: " << DEFAULT_TEXT_BUFFER_SIZE << "\n";
217 }
218 
print_help(const char * prog_name)219 static void print_help(const char *prog_name) {
220   printf("Usage: %s [OPTION]...\n" PACKAGE_NAME
221          " is a system monitor that renders text on desktop or to own "
222          "transparent\n"
223          "window. Command line options will override configurations defined in "
224          "config\n"
225          "file.\n"
226          "   -v, --version             version\n"
227          "   -q, --quiet               quiet mode\n"
228          "   -D, --debug               increase debugging output, ie. -DD for "
229          "more debugging\n"
230          "   -c, --config=FILE         config file to load\n"
231 #ifdef BUILD_BUILTIN_CONFIG
232          "   -C, --print-config        print the builtin default config to "
233          "stdout\n"
234          "                             e.g. 'conky -C > ~/.conkyrc' will "
235          "create a new default config\n"
236 #endif
237          "   -d, --daemonize           daemonize, fork to background\n"
238          "   -h, --help                help\n"
239 #ifdef BUILD_X11
240          "   -a, --alignment=ALIGNMENT text alignment on screen, "
241          "{top,bottom,middle}_{left,right,middle}\n"
242          "   -X, --display=DISPLAY     X11 display to use\n"
243          "   -m, --xinerama-head=N     Xinerama monitor index (0=first)\n"
244          "   -f, --font=FONT           font to use\n"
245 #ifdef OWN_WINDOW
246          "   -o, --own-window          create own window to draw\n"
247 #endif
248          "   -b, --double-buffer       double buffer (prevents flickering)\n"
249          "   -w, --window-id=WIN_ID    window id to draw\n"
250          "   -x X                      x position\n"
251          "   -y Y                      y position\n"
252 #endif /* BUILD_X11 */
253          "   -t, --text=TEXT           text to render, remember single quotes, "
254          "like -t '$uptime'\n"
255          "   -u, --interval=SECS       update interval\n"
256          "   -i COUNT                  number of times to update " PACKAGE_NAME
257          " (and quit)\n"
258          "   -p, --pause=SECS          pause for SECS seconds at startup "
259          "before doing anything\n",
260          prog_name);
261 }
262 
reset_optind()263 inline void reset_optind() {
264 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
265     defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
266   optind = optreset = 1;
267 #else
268   optind = 0;
269 #endif
270 }
271 
main(int argc,char ** argv)272 int main(int argc, char **argv) {
273 #ifdef BUILD_I18N
274   setlocale(LC_ALL, "");
275   bindtextdomain(PACKAGE_NAME, LOCALE_DIR);
276   textdomain(PACKAGE_NAME);
277 #endif
278   argc_copy = argc;
279   argv_copy = argv;
280   g_sigterm_pending = 0;
281   g_sighup_pending = 0;
282   g_sigusr2_pending = 0;
283 
284 #ifdef BUILD_CURL
285   struct curl_global_initializer {
286     curl_global_initializer() {
287       if (curl_global_init(CURL_GLOBAL_ALL)) {
288         NORM_ERR(
289             "curl_global_init() failed, you may not be able to use curl "
290             "variables");
291       }
292     }
293     ~curl_global_initializer() { curl_global_cleanup(); }
294   };
295   curl_global_initializer curl_global;
296 #endif
297 
298   /* handle command line parameters that don't change configs */
299 #ifdef BUILD_X11
300   if (!setlocale(LC_CTYPE, "")) {
301     NORM_ERR("Can't set the specified locale!\nCheck LANG, LC_CTYPE, LC_ALL.");
302   }
303 #endif /* BUILD_X11 */
304   while (1) {
305     int c = getopt_long(argc, argv, getopt_string, longopts, nullptr);
306 
307     if (c == -1) { break; }
308 
309     switch (c) {
310       case 'D':
311         global_debug_level++;
312         break;
313       case 'v':
314       case 'V':
315         print_version();
316         return EXIT_SUCCESS;
317       case 'c':
318         current_config = optarg;
319         break;
320       case 'q':
321         if (freopen("/dev/null", "w", stderr) == nullptr) {
322           CRIT_ERR(nullptr, nullptr, "could not open /dev/null as stderr!");
323         }
324         break;
325       case 'h':
326         print_help(argv[0]);
327         return 0;
328 #ifdef BUILD_BUILTIN_CONFIG
329       case 'C':
330         std::cout << defconfig;
331         return 0;
332 #endif
333 #ifdef BUILD_X11
334       case 'w':
335         window.window = strtol(optarg, nullptr, 0);
336         break;
337 #endif /* BUILD_X11 */
338 
339       case '?':
340         return EXIT_FAILURE;
341     }
342   }
343 
344   try {
345     set_current_config();
346 
347     state = std::make_unique<lua::state>();
348 
349     conky::export_symbols(*state);
350 
351     setup_inotify();
352 
353     initialisation(argc, argv);
354 
355     first_pass = 0; /* don't ever call fork() again */
356 
357     main_loop();
358   } catch (fork_throw &e) {
359     return EXIT_SUCCESS;
360   } catch (unknown_arg_throw &e) {
361     return EXIT_FAILURE;
362   } catch (obj_create_error &e) {
363     std::cerr << e.what() << std::endl;
364     clean_up(nullptr, nullptr);
365     return EXIT_FAILURE;
366   } catch (std::exception &e) {
367     std::cerr << PACKAGE_NAME ": " << e.what() << std::endl;
368     return EXIT_FAILURE;
369   }
370 
371 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
372   kvm_close(kd);
373 #endif
374 
375 #ifdef LEAKFREE_NCURSES
376   _nc_free_and_exit(0);  // hide false memleaks
377 #endif
378   return 0;
379 }
380