Merge branch 'readme' of git://repo.or.cz/notion/jeffpc into readme
[notion.git] / utils / ion-statusd / ion-statusd.c
blobf0f0b39b90037643685b093647f1467b82ec1499
1 /*
2 * ion/utils/ion-statusd/ion-statusd.c
4 * Copyright (c) Tuomo Valkonen 2004-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
15 #include <libtu/util.h>
16 #include <libtu/optparser.h>
17 #include <libtu/errorlog.h>
18 #include <libtu/locale.h>
19 #include <libtu/misc.h>
20 #include <libtu/prefix.h>
21 #include <libextl/readconfig.h>
22 #include <libmainloop/select.h>
23 #include <libmainloop/signal.h>
24 #include <libmainloop/defer.h>
26 #ifndef CF_NO_LOCALE
27 #include <locale.h>
28 #endif
30 #include "../../version.h"
33 static OptParserOpt ion_opts[]={
34 /*{OPT_ID('d'), "display", OPT_ARG, "host:dpy.scr",
35 DUMMY_TR("X display to use")},*/
37 {'c', "conffile", OPT_ARG, "config_file",
38 DUMMY_TR("Configuration file")},
40 {'s', "searchdir", OPT_ARG, "dir",
41 DUMMY_TR("Add directory to search path")},
43 /*{OPT_ID('s'), "session", OPT_ARG, "session_name",
44 DUMMY_TR("Name of session (affects savefiles)")},*/
46 {'h', "help", 0, NULL,
47 DUMMY_TR("Show this help")},
49 {'V', "version", 0, NULL,
50 DUMMY_TR("Show program version")},
52 {OPT_ID('a'), "about", 0, NULL,
53 DUMMY_TR("Show about text")},
55 {'q', "quiet", 0, NULL,
56 DUMMY_TR("Quiet mode")},
58 {'m', "meter", OPT_ARG, "meter_module",
59 DUMMY_TR("Load a meter module")},
61 END_OPTPARSEROPTS
65 static const char statusd_copy[]=
66 "Ion-statusd " ION_VERSION ", copyright (c) Tuomo Valkonen 2004-2009.";
69 static const char statusd_license[]=DUMMY_TR(
70 "This software is licensed under the GNU Lesser General Public License\n"
71 "(LGPL), version 2.1, extended with terms applying to the use of the name\n"
72 "of the project, Ion(tm), unless otherwise indicated in components taken\n"
73 "from elsewhere. For details, see the file LICENSE that you should have\n"
74 "received with this software.\n"
75 "\n"
76 "This program is distributed in the hope that it will be useful,\n"
77 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
78 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
81 /* new_informs=TRUE because we should always print period when
82 * initialisation is done.
84 static bool new_informs=TRUE;
85 static ExtlTab configtab;
87 static void help()
89 int i;
90 printf(TR("Usage: %s [options]\n\n"), libtu_progname());
91 for(i=0; ion_opts[i].descr!=NULL; i++)
92 ion_opts[i].descr=TR(ion_opts[i].descr);
93 optparser_printhelp(OPTP_MIDLONG, ion_opts);
94 printf("\n");
98 static void flush_informs()
100 if(new_informs){
101 printf(".\n");
102 fflush(stdout);
103 new_informs=FALSE;
108 static void mainloop()
110 sigset_t trapset;
112 sigemptyset(&trapset);
113 sigaddset(&trapset, SIGALRM);
114 sigaddset(&trapset, SIGCHLD);
115 mainloop_trap_signals(&trapset);
117 while(1){
118 int kill_sig=mainloop_check_signals();
119 if(kill_sig!=0 && kill_sig!=SIGUSR1){
120 if(kill_sig==SIGTERM)
121 exit(EXIT_FAILURE);
122 else
123 kill(getpid(), kill_sig);
126 mainloop_execute_deferred();
128 flush_informs();
130 mainloop_select();
135 extern bool statusd_register_exports();
136 extern void statusd_unregister_exports();
139 static void stdout_closed(int fd, void *data)
141 exit(EXIT_SUCCESS);
145 int main(int argc, char*argv[])
147 const char *mod=NULL;
148 char *mod2=NULL;
149 int loaded=0;
150 int opt;
151 bool quiet=FALSE;
153 #ifndef CF_NO_LOCALE
154 if(setlocale(LC_ALL, "")==NULL)
155 warn("setlocale() call failed.");
156 #endif
158 configtab=extl_table_none();
160 libtu_init(argv[0]);
162 #ifdef CF_RELOCATABLE_BIN_LOCATION
163 prefix_set(argv[0], CF_RELOCATABLE_BIN_LOCATION);
164 #endif
166 extl_init();
168 if(!statusd_register_exports())
169 return EXIT_FAILURE;
171 prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR);
172 prefix_wrap_simple(extl_add_searchdir, MODULEDIR);
173 prefix_wrap_simple(extl_add_searchdir, ETCDIR);
174 prefix_wrap_simple(extl_add_searchdir, SHAREDIR);
175 prefix_wrap_simple(extl_add_searchdir, LCDIR);
176 extl_set_userdirs(CF_ION_EXECUTABLE);
178 optparser_init(argc, argv, OPTP_MIDLONG, ion_opts);
180 extl_read_config("ioncore_luaext", NULL, TRUE);
182 while((opt=optparser_get_opt())){
183 switch(opt){
184 /*case OPT_ID('d'):
185 display=optparser_get_arg();
186 break;*/
187 case 's':
188 extl_add_searchdir(optparser_get_arg());
189 break;
190 /*case OPT_ID('s'):
191 extl_set_sessiondir(optparser_get_arg());
192 break;*/
193 case 'h':
194 help();
195 return EXIT_SUCCESS;
196 case 'V':
197 printf("%s\n", ION_VERSION);
198 return EXIT_SUCCESS;
199 case OPT_ID('a'):
200 printf("%s\n\n%s", statusd_copy, TR(statusd_license));
201 return EXIT_SUCCESS;
202 case 'c':
204 ExtlTab t;
205 const char *f=optparser_get_arg();
206 if(extl_read_savefile(f, &t)){
207 extl_unref_table(configtab);
208 configtab=t;
209 }else{
210 warn(TR("Unable to load configuration file %s"), f);
213 break;
214 case 'q':
215 quiet=TRUE;
216 break;
217 case 'm':
218 mod=optparser_get_arg();
219 if(strchr(mod, '/')==NULL && strchr(mod, '.')==NULL){
220 mod2=scat("statusd_", mod);
221 if(mod2==NULL)
222 return EXIT_FAILURE;
223 mod=mod2;
225 if(extl_read_config(mod, NULL, !quiet))
226 loaded++;
227 if(mod2!=NULL)
228 free(mod2);
229 break;
230 default:
231 warn(TR("Invalid command line."));
232 help();
233 return EXIT_FAILURE;
237 if(loaded==0 && !quiet){
238 warn(TR("No meters loaded."));
239 return EXIT_FAILURE;
242 mainloop();
244 return EXIT_SUCCESS;
248 /*EXTL_DOC
249 * Inform that meter \var{name} has value \var{value}.
251 EXTL_EXPORT
252 void statusd_inform(const char *name, const char *value)
254 printf("%s: %s\n", name, value);
255 new_informs=TRUE;
259 /*EXTL_DOC
260 * Get configuration table for module \var{name}
262 EXTL_EXPORT
263 ExtlTab statusd_get_config(const char *name)
265 if(name==NULL){
266 return extl_ref_table(configtab);
267 }else{
268 ExtlTab t;
269 if(extl_table_gets_t(configtab, name, &t))
270 return t;
271 else
272 return extl_create_table();
277 /*EXTL_DOC
278 * Get last file modification time.
280 EXTL_EXPORT
281 double statusd_last_modified(const char *fname)
283 struct stat st;
285 if(fname==NULL)
286 return (double)(-1);
288 if(stat(fname, &st)!=0){
289 /*warn_err_obj(fname);*/
290 return (double)(-1);
293 return (double)(st.st_mtime>st.st_ctime ? st.st_mtime : st.st_ctime);
297 EXTL_EXPORT
298 ExtlTab statusd_getloadavg()
300 ExtlTab t=extl_create_table();
301 #ifndef CF_NO_GETLOADAVG
302 double l[3];
303 int n;
305 n=getloadavg(l, 3);
307 if(n>=1)
308 extl_table_sets_d(t, "1min", l[0]);
309 if(n>=2)
310 extl_table_sets_d(t, "5min", l[1]);
311 if(n>=3)
312 extl_table_sets_d(t, "15min", l[2]);
313 #endif
314 return t;