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