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