]> git.decadent.org.uk Git - ion3.git/blob - utils/ion-statusd/ion-statusd.c
5822fe6f897ea850489a00e39613eb408db2d505
[ion3.git] / utils / ion-statusd / ion-statusd.c
1 /*
2  * ion/utils/ion-statusd/ion-statusd.c
3  *
4  * Copyright (c) Tuomo Valkonen 2004-2006.
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <string.h>
13 #include <unistd.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16
17 #include <libtu/util.h>
18 #include <libtu/optparser.h>
19 #include <libtu/errorlog.h>
20 #include <libtu/locale.h>
21 #include <libtu/misc.h>
22 #include <libtu/prefix.h>
23 #include <libextl/readconfig.h>
24 #include <libmainloop/select.h>
25 #include <libmainloop/signal.h>
26 #include <libmainloop/defer.h>
27
28 #ifndef CF_NO_LOCALE
29 #include <locale.h>
30 #endif
31
32 #include "../../version.h"
33
34
35 static OptParserOpt ion_opts[]={
36     /*{OPT_ID('d'), "display",  OPT_ARG, "host:dpy.scr", 
37      DUMMY_TR("X display to use")},*/
38     
39     {'c', "conffile", OPT_ARG, "config_file", 
40      DUMMY_TR("Configuration file")},
41     
42     {'s', "searchdir", OPT_ARG, "dir", 
43      DUMMY_TR("Add directory to search path")},
44
45     /*{OPT_ID('s'), "session",  OPT_ARG, "session_name", 
46      DUMMY_TR("Name of session (affects savefiles)")},*/
47     
48     {'h', "help", 0, NULL, 
49      DUMMY_TR("Show this help")},
50     
51     {'V', "version", 0, NULL,
52      DUMMY_TR("Show program version")},
53     
54     {OPT_ID('a'), "about", 0, NULL,
55      DUMMY_TR("Show about text")},
56
57     {'q', "quiet", 0, NULL, 
58      DUMMY_TR("Quiet mode")},
59
60     {'m', "meter", OPT_ARG, "meter_module",
61      DUMMY_TR("Load a meter module")},
62
63     END_OPTPARSEROPTS
64 };
65
66
67 static const char statusd_copy[]=
68     "Ion-statusd " ION_VERSION ", copyright (c) Tuomo Valkonen 2004-2005.";
69
70
71 static const char statusd_license[]=DUMMY_TR(
72     "This program is free software; you can redistribute it and/or\n"
73     "modify it under the terms of the GNU Lesser General Public\n"
74     "License as published by the Free Software Foundation; either\n"
75     "version 2.1 of the License, or (at your option) any later version.\n"
76     "\n"
77     "This program is distributed in the hope that it will be useful,\n"
78     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
79     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
80     "Lesser General Public License for more details.\n");
81
82
83 /* new_informs=TRUE because we should always print period when 
84  * initialisation is done. 
85  */
86 static bool new_informs=TRUE;
87 static ExtlTab configtab;
88
89 static void help()
90 {
91     int i;
92     printf(TR("Usage: %s [options]\n\n"), libtu_progname());
93     for(i=0; ion_opts[i].descr!=NULL; i++)
94         ion_opts[i].descr=TR(ion_opts[i].descr);
95     optparser_printhelp(OPTP_MIDLONG, ion_opts);
96     printf("\n");
97 }
98
99
100 static void flush_informs()
101 {
102     if(new_informs){
103         printf(".\n");
104         fflush(stdout);
105         new_informs=FALSE;
106     }
107 }
108
109
110 static void mainloop()
111 {
112     sigset_t trapset;
113     
114     sigemptyset(&trapset);
115     sigaddset(&trapset, SIGALRM);
116     sigaddset(&trapset, SIGCHLD);
117     mainloop_trap_signals(&trapset);
118     
119     while(1){
120         int kill_sig=mainloop_check_signals();
121         if(kill_sig!=0 && kill_sig!=SIGUSR1){
122             if(kill_sig==SIGTERM)
123                 exit(EXIT_FAILURE);
124             else
125                 kill(getpid(), kill_sig);
126         }
127
128         mainloop_execute_deferred();
129
130         flush_informs();
131
132         mainloop_select();
133     }
134 }
135
136
137 extern bool statusd_register_exports();
138 extern void statusd_unregister_exports();
139
140
141 static void stdout_closed(int fd, void *data)
142 {
143     exit(EXIT_SUCCESS);
144 }
145
146
147 int main(int argc, char*argv[])
148 {
149     const char *mod=NULL;
150     char *mod2=NULL;
151     int loaded=0;
152     int opt;
153     bool quiet=FALSE;
154
155 #ifndef CF_NO_LOCALE    
156     if(setlocale(LC_ALL, "")==NULL)
157         warn("setlocale() call failed.");
158 #endif
159
160     configtab=extl_table_none();
161     
162     libtu_init(argv[0]);
163
164 #ifdef CF_RELOCATABLE    
165     prefix_set(argv[0], STATUSD_LOCATION);
166 #endif
167
168     extl_init();
169     
170     if(!statusd_register_exports())
171         return EXIT_FAILURE;
172
173     prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR);
174     prefix_wrap_simple(extl_add_searchdir, MODULEDIR);
175     prefix_wrap_simple(extl_add_searchdir, ETCDIR);
176     prefix_wrap_simple(extl_add_searchdir, SHAREDIR);
177     prefix_wrap_simple(extl_add_searchdir, LCDIR);
178     extl_set_userdirs("ion3");
179
180     optparser_init(argc, argv, OPTP_MIDLONG, ion_opts);
181     
182     extl_read_config("ioncore_luaext", NULL, TRUE);
183     
184     while((opt=optparser_get_opt())){
185         switch(opt){
186         /*case OPT_ID('d'):
187             display=optparser_get_arg();
188             break;*/
189         case 's':
190             extl_add_searchdir(optparser_get_arg());
191             break;
192         /*case OPT_ID('s'):
193             extl_set_sessiondir(optparser_get_arg());
194             break;*/
195         case 'h':
196             help();
197             return EXIT_SUCCESS;
198         case 'V':
199             printf("%s\n", ION_VERSION);
200             return EXIT_SUCCESS;
201         case OPT_ID('a'):
202             printf("%s\n\n%s", statusd_copy, TR(statusd_license));
203             return EXIT_SUCCESS;
204         case 'c':
205             {
206                 ExtlTab t;
207                 const char *f=optparser_get_arg();
208                 if(extl_read_savefile(f, &t)){
209                     extl_unref_table(configtab);
210                     configtab=t;
211                 }else{
212                     warn(TR("Unable to load configuration file %s"), f);
213                 }
214             }
215             break;
216         case 'q':
217             quiet=TRUE;
218             break;
219         case 'm':
220             mod=optparser_get_arg();
221             if(strchr(mod, '/')==NULL && strchr(mod, '.')==NULL){
222                 mod2=scat("statusd_", mod);
223                 if(mod2==NULL)
224                     return EXIT_FAILURE;
225                 mod=mod2;
226             }
227             if(extl_read_config(mod, NULL, !quiet))
228                 loaded++;
229             if(mod2!=NULL)
230                 free(mod2);
231             break;
232         default:
233             warn(TR("Invalid command line."));
234             help();
235             return EXIT_FAILURE;
236         }
237     }
238     
239     if(loaded==0 && !quiet){
240         warn(TR("No meters loaded."));
241         return EXIT_FAILURE;
242     }
243     
244     mainloop();
245     
246     return EXIT_SUCCESS;
247 }
248
249
250 /*EXTL_DOC
251  * Inform that meter \var{name} has value \var{value}.
252  */
253 EXTL_EXPORT
254 void statusd_inform(const char *name, const char *value)
255 {
256     printf("%s: %s\n", name, value);
257     new_informs=TRUE;
258 }
259
260
261 /*EXTL_DOC
262  * Get configuration table for module \var{name}
263  */
264 EXTL_EXPORT
265 ExtlTab statusd_get_config(const char *name)
266 {
267     if(name==NULL){
268         return extl_ref_table(configtab);
269     }else{
270         ExtlTab t;
271         if(extl_table_gets_t(configtab, name, &t))
272             return t;
273         else
274             return extl_create_table();
275     }
276 }
277
278
279 /*EXTL_DOC
280  * Get last file modification time.
281  */
282 EXTL_EXPORT
283 double statusd_last_modified(const char *fname)
284 {
285     struct stat st;
286     
287     if(fname==NULL)
288         return (double)(-1);
289     
290     if(stat(fname, &st)!=0){
291         /*warn_err_obj(fname);*/
292         return (double)(-1);
293     }
294     
295     return (double)(st.st_mtime>st.st_ctime ? st.st_mtime : st.st_ctime);
296 }
297
298
299 EXTL_EXPORT
300 ExtlTab statusd_getloadavg()
301 {
302     ExtlTab t=extl_create_table();
303     double l[3];
304     int n;
305     
306     n=getloadavg(l, 3);
307     
308     if(n>=1)
309         extl_table_sets_d(t, "1min", l[0]);
310     if(n>=2)
311         extl_table_sets_d(t, "5min", l[1]);
312     if(n>=3)
313         extl_table_sets_d(t, "15min", l[2]);
314         
315     return t;
316 }
317