]> git.decadent.org.uk Git - ion3.git/blob - pwm/pwm.c
c4a080474a9458aca9e25b9e144b729563bef60b
[ion3.git] / pwm / pwm.c
1 /*
2  * ion/pwm/pwm.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
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 <stdlib.h>
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21
22 #include <libtu/util.h>
23 #include <libtu/optparser.h>
24 #include <libtu/errorlog.h>
25 #include <libextl/readconfig.h>
26 #include <libmainloop/exec.h>
27
28 #include <ioncore/common.h>
29 #include <ioncore/global.h>
30 #include <ioncore/ioncore.h>
31 #include <ioncore/exec.h>
32 #include <ioncore/event.h>
33 #include "../version.h"
34
35
36 /* Options. Getopt is not used because getopt_long is quite gnu-specific
37  * and they don't know of '-display foo' -style args anyway.
38  * Instead, I've reinvented the wheel in libtu :(.
39  */
40 static OptParserOpt pwm_opts[]={
41     {OPT_ID('d'), "display",  OPT_ARG, "host:dpy.scr", 
42      DUMMY_TR("X display to use")},
43     
44     {'c', "conffile", OPT_ARG, "config_file", 
45      DUMMY_TR("Configuration file")},
46     
47     {'s', "searchdir", OPT_ARG, "dir", 
48      DUMMY_TR("Add directory to search path")},
49
50     {OPT_ID('o'), "oneroot",  0, NULL,
51      DUMMY_TR("Manage default screen only")},
52
53     {OPT_ID('s'), "session",  OPT_ARG, "session_name", 
54      DUMMY_TR("Name of session (affects savefiles)")},
55     
56     {OPT_ID('S'), "smclientid", OPT_ARG, "client_id", 
57      DUMMY_TR("Session manager client ID")},
58
59     {OPT_ID('N'), "noerrorlog", 0, NULL, 
60      DUMMY_TR("Do not create startup error log and display it "
61               "with xmessage.")},
62     
63     {'h', "help", 0, NULL, 
64      DUMMY_TR("Show this help")},
65     
66     {'V', "version", 0, NULL,
67      DUMMY_TR("Show program version")},
68     
69     {OPT_ID('a'), "about", 0, NULL,
70      DUMMY_TR("Show about text")},
71     
72     END_OPTPARSEROPTS
73 };
74
75
76 static void help()
77 {
78     int i;
79     printf(TR("Usage: %s [options]\n\n"), libtu_progname());
80     for(i=0; pwm_opts[i].descr!=NULL; i++)
81         pwm_opts[i].descr=TR(pwm_opts[i].descr);
82     optparser_printhelp(OPTP_MIDLONG, pwm_opts);
83     printf("\n");
84 }
85
86
87 int main(int argc, char*argv[])
88 {
89     const char *cfgfile="cfg_pwm";
90     const char *display=NULL;
91     char *cmd=NULL;
92     int stflags=0;
93     int opt;
94     ErrorLog el;
95     FILE *ef=NULL;
96     char *efnam=NULL;
97     bool may_continue=FALSE;
98     bool noerrorlog=FALSE;
99
100     libtu_init(argv[0]);
101
102     if(!ioncore_init("pwm3", argc, argv, LOCALEDIR))
103         return EXIT_FAILURE;
104
105     extl_add_searchdir(EXTRABINDIR); /* ion-completefile */
106     extl_add_searchdir(MODULEDIR);
107     extl_add_searchdir(ETCDIR);
108 #ifdef PWM_ETCDIR    
109     extl_add_searchdir(PWM_ETCDIR);
110 #endif
111     extl_add_searchdir(SHAREDIR);
112     extl_add_searchdir(LCDIR);
113     extl_set_userdirs("pwm3");
114
115     optparser_init(argc, argv, OPTP_MIDLONG, pwm_opts);
116     
117     while((opt=optparser_get_opt())){
118         switch(opt){
119         case OPT_ID('d'):
120             display=optparser_get_arg();
121             break;
122         case 'c':
123             cfgfile=optparser_get_arg();
124             break;
125         case 's':
126             extl_add_searchdir(optparser_get_arg());
127             break;
128         case OPT_ID('S'):
129             ioncore_g.sm_client_id=optparser_get_arg();
130             break;
131         case OPT_ID('o'):
132             stflags|=IONCORE_STARTUP_ONEROOT;
133             break;
134         case OPT_ID('s'):
135             extl_set_sessiondir(optparser_get_arg());
136             break;
137         case OPT_ID('N'):
138             noerrorlog=TRUE;
139             break;
140         case 'h':
141             help();
142             return EXIT_SUCCESS;
143         case 'V':
144             printf("%s\n", ION_VERSION);
145             return EXIT_SUCCESS;
146         case OPT_ID('a'):
147             printf("%s\n", ioncore_aboutmsg());
148             return EXIT_SUCCESS;
149         default:
150             warn(TR("Invalid command line."));
151             help();
152             return EXIT_FAILURE;
153         }
154     }
155
156     if(!noerrorlog){
157         /* We may have to pass the file to xmessage so just using tmpfile()
158          * isn't sufficient.
159          */
160         libtu_asprintf(&efnam, "%s/pwm-%d-startup-errorlog", P_tmpdir,
161                        getpid());
162         if(efnam==NULL){
163             warn_err();
164         }else{
165             ef=fopen(efnam, "wt");
166             if(ef==NULL){
167                 warn_err_obj(efnam);
168                 free(efnam);
169                 efnam=NULL;
170             }else{
171                 cloexec_braindamage_fix(fileno(ef));
172                 fprintf(ef, TR("PWM startup error log:\n"));
173                 errorlog_begin_file(&el, ef);
174             }
175         }
176     }
177
178     if(ioncore_startup(display, cfgfile, stflags))
179         may_continue=TRUE;
180
181 fail:
182     if(!may_continue)
183         warn(TR("Refusing to start due to encountered errors."));
184     
185     if(ef!=NULL){
186         pid_t pid=-1;
187         if(errorlog_end(&el) && ioncore_g.dpy!=NULL){
188             fclose(ef);
189             pid=fork();
190             if(pid==0){
191                 ioncore_setup_display(DefaultScreen(ioncore_g.dpy));
192                 if(!may_continue)
193                     XCloseDisplay(ioncore_g.dpy);
194                 else
195                     close(ioncore_g.conn);
196                 libtu_asprintf(&cmd, CF_XMESSAGE " %s", efnam);
197                 if(cmd==NULL){
198                     warn_err();
199                 }else if(system(cmd)==-1){
200                     warn_err_obj(cmd);
201                 }
202                 unlink(efnam);
203                 exit(EXIT_SUCCESS);
204             }
205             if(!may_continue && pid>0)
206                 waitpid(pid, NULL, 0);
207         }else{
208             fclose(ef);
209         }
210         if(pid<0)
211             unlink(efnam);
212         free(efnam);
213     }
214
215     if(!may_continue)
216         return EXIT_FAILURE;
217     
218     ioncore_mainloop();
219     
220     /* The code should never return here */
221     return EXIT_SUCCESS;
222 }