]> git.decadent.org.uk Git - ion3.git/blob - pwm/pwm.c
[svn-inject] Installing original source of ion3
[ion3.git] / pwm / pwm.c
1 /*
2  * ion/pwm/pwm.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-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 <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 root window/non-Xinerama screen only")},
52
53 #if defined(CF_XINERAMA) || defined(CF_SUN_XINERAMA)
54     {OPT_ID('x'), "xinerama", OPT_ARG, "1|0",
55      DUMMY_TR("Use Xinerama screen information (default: 0/no)")},
56 #else
57     {OPT_ID('x'), "xinerama", OPT_ARG, "?",
58      DUMMY_TR("Ignored: not compiled with Xinerama support")},
59 #endif
60     
61     {OPT_ID('s'), "session",  OPT_ARG, "session_name", 
62      DUMMY_TR("Name of session (affects savefiles)")},
63     
64     {OPT_ID('S'), "smclientid", OPT_ARG, "client_id", 
65      DUMMY_TR("Session manager client ID")},
66
67     {OPT_ID('N'), "noerrorlog", 0, NULL, 
68      DUMMY_TR("Do not create startup error log and display it "
69               "with xmessage.")},
70     
71     {'h', "help", 0, NULL, 
72      DUMMY_TR("Show this help")},
73     
74     {'V', "version", 0, NULL,
75      DUMMY_TR("Show program version")},
76     
77     {OPT_ID('a'), "about", 0, NULL,
78      DUMMY_TR("Show about text")},
79     
80     END_OPTPARSEROPTS
81 };
82
83
84 static void help()
85 {
86     int i;
87     printf(TR("Usage: %s [options]\n\n"), prog_execname());
88     for(i=0; pwm_opts[i].descr!=NULL; i++)
89         pwm_opts[i].descr=TR(pwm_opts[i].descr);
90     optparser_printhelp(OPTP_MIDLONG, pwm_opts);
91     printf("\n");
92 }
93
94
95 int main(int argc, char*argv[])
96 {
97     const char *cfgfile="cfg_pwm";
98     const char *display=NULL;
99     char *cmd=NULL;
100     int stflags=IONCORE_STARTUP_NOXINERAMA;
101     int opt;
102     ErrorLog el;
103     FILE *ef=NULL;
104     char *efnam=NULL;
105     bool may_continue=FALSE;
106     bool noerrorlog=FALSE;
107
108     libtu_init(argv[0]);
109
110     if(!ioncore_init("pwm3", argc, argv, LOCALEDIR))
111         return EXIT_FAILURE;
112
113     extl_add_searchdir(EXTRABINDIR); /* ion-completefile */
114     extl_add_searchdir(MODULEDIR);
115     extl_add_searchdir(ETCDIR);
116 #ifdef PWM_ETCDIR    
117     extl_add_searchdir(PWM_ETCDIR);
118 #endif
119     extl_add_searchdir(SHAREDIR);
120     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('x'):
143             {
144                 const char *p=optparser_get_arg();
145                 if(strcmp(p, "1")==0)
146                     stflags&=~IONCORE_STARTUP_NOXINERAMA;
147                 else if(strcmp(p, "0")==0)
148                     stflags|=IONCORE_STARTUP_NOXINERAMA;
149                 else
150                     warn(TR("Invalid parameter to -xinerama."));
151             }
152             break;
153         case OPT_ID('s'):
154             extl_set_sessiondir(optparser_get_arg());
155             break;
156         case OPT_ID('N'):
157             noerrorlog=TRUE;
158             break;
159         case 'h':
160             help();
161             return EXIT_SUCCESS;
162         case 'V':
163             printf("%s\n", ION_VERSION);
164             return EXIT_SUCCESS;
165         case OPT_ID('a'):
166             printf("%s\n", ioncore_aboutmsg());
167             return EXIT_SUCCESS;
168         default:
169             warn(TR("Invalid command line."));
170             help();
171             return EXIT_FAILURE;
172         }
173     }
174
175     if(!noerrorlog){
176         /* We may have to pass the file to xmessage so just using tmpfile()
177          * isn't sufficient.
178          */
179         libtu_asprintf(&efnam, "%s/pwm-%d-startup-errorlog", P_tmpdir,
180                        getpid());
181         if(efnam==NULL){
182             warn_err();
183         }else{
184             ef=fopen(efnam, "wt");
185             if(ef==NULL){
186                 warn_err_obj(efnam);
187                 free(efnam);
188                 efnam=NULL;
189             }else{
190                 cloexec_braindamage_fix(fileno(ef));
191                 fprintf(ef, TR("PWM startup error log:\n"));
192                 errorlog_begin_file(&el, ef);
193             }
194         }
195     }
196
197     if(ioncore_startup(display, cfgfile, stflags))
198         may_continue=TRUE;
199
200 fail:
201     if(!may_continue)
202         warn(TR("Refusing to start due to encountered errors."));
203     
204     if(ef!=NULL){
205         pid_t pid=-1;
206         if(errorlog_end(&el) && ioncore_g.dpy!=NULL){
207             fclose(ef);
208             pid=fork();
209             if(pid==0){
210                 ioncore_setup_environ(DefaultScreen(ioncore_g.dpy));
211                 if(!may_continue)
212                     XCloseDisplay(ioncore_g.dpy);
213                 else
214                     close(ioncore_g.conn);
215                 libtu_asprintf(&cmd, CF_XMESSAGE " %s", efnam);
216                 if(cmd==NULL){
217                     warn_err();
218                 }else if(system(cmd)==-1){
219                     warn_err_obj(cmd);
220                 }
221                 unlink(efnam);
222                 exit(EXIT_SUCCESS);
223             }
224             if(!may_continue && pid>0)
225                 waitpid(pid, NULL, 0);
226         }else{
227             fclose(ef);
228         }
229         if(pid<0)
230             unlink(efnam);
231         free(efnam);
232     }
233
234     if(!may_continue)
235         return EXIT_FAILURE;
236     
237     ioncore_mainloop();
238     
239     /* The code should never return here */
240     return EXIT_SUCCESS;
241 }