Change to the linux kernel coding style
[wmaker-crm.git] / util / wmsetup.c
1 /* wmsetup.c- create wmaker config file dir structure and copy default
2 * config files.
3 *
4 * Copyright (c) 2000-2003 Alfredo K. Kojima
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 #if 1
21 int main()
22 {
23 }
24 #else
25 #define PROG_VERSION "wmsetup 0.0 (Window Maker)"
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <unistd.h>
30
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34
35 #include <WINGs/WINGs.h>
36
37 #include "../src/config.h"
38
39 char *RequiredDirectories[] = {
40 "/Defaults",
41 "/Library",
42 "/Library/Icons",
43 "/Library/WindowMaker",
44 "/Library/WindowMaker/Backgrounds",
45 "/Library/WindowMaker/IconSets",
46 "/Library/WindowMaker/Pixmaps",
47 "/Library/WindowMaker/CachedPixmaps",
48 "/Library/WindowMaker/SoundSets",
49 "/Library/WindowMaker/Sounds",
50 "/Library/WindowMaker/Styles",
51 "/Library/WindowMaker/Themes",
52 "/Library/WindowMaker/WPrefs",
53 NULL
54 };
55
56 char *RequiredFiles[] = {
57 "/Defaults/WindowMaker",
58 "/Defaults/WMWindowAttributes",
59 NULL
60 };
61
62 WMScreen *scr;
63
64 #define wlog wwarning
65
66 #if 0
67 void wlog(const char *msg, ...)
68 {
69 va_list args;
70 char buf[MAXLINE];
71
72 va_start(args, msg);
73
74 vsprintf(buf, msg, args);
75 puts(buf);
76
77 va_end(args);
78 }
79 #endif
80
81 void alert(const char *msg, ...)
82 {
83 va_list args;
84 char buffer[2048];
85
86 va_start(args, msg);
87
88 vsprintf(buf, msg, args);
89
90 WMRunAlertPanel(scr, NULL, _("Error"), buffer, _("OK"), NULL, NULL);
91
92 va_end(args);
93 }
94
95 Bool ask(char *title, char *yes, char *no, const char *msg, ...)
96 {
97 va_list args;
98 char buffer[2048];
99
100 va_start(args, msg);
101
102 vsprintf(buf, msg, args);
103
104 WMRunAlertPanel(scr, NULL, title, buffer, yes, no, NULL);
105
106 va_end(args);
107 }
108
109 char *renameName(char *path)
110 {
111 char *buf = wmalloc(strlen(path) + 8);
112 int i;
113
114 sprintf(buf, "%s~", path);
115
116 if (access(buf, F_OK) < 0) {
117 return buf;
118 }
119
120 for (i = 0; i < 10; i++) {
121 sprintf(buf, "%s~%i", path, i);
122
123 if (access(buf, F_OK) < 0) {
124 return buf;
125 }
126 }
127
128 sprintf(buf, "%s~", path);
129
130 return buf;
131 }
132
133 void showFileError(int error, Bool directory, char *path)
134 {
135 switch (error) {
136 case EACCESS:
137 if (directory) {
138 alert(_("The directory %s needs to be fully accessible, but is\n"
139 "not. Make sure all of it's parent directories have\n"
140 "read and execute permissions set."), path);
141 } else {
142 alert(_("The file %s needs to be fully accessible, but is not.\n"
143 "Make sure it has read and write permissions set and\n"
144 "all of it's parent directories have read and execute\n" "permissions."), path);
145 }
146 break;
147
148 case EROFS:
149 alert(_("The %s %s is in a read-only file system, but it needs to be\n"
150 "writable. Start wmaker with the --static command line option."),
151 directory ? _("directory") : _("file"), path);
152 break;
153
154 default:
155 alert(_("An error occurred while accessing the %s %s. Please make sure\n"
156 "it exists and is accessible.\n%s"),
157 directory ? _("directory") : _("file"), path, wstrerror(error));
158 break;
159 }
160 }
161
162 Bool checkDir(char *path, Bool fatal)
163 {
164 if (access(path, F_OK) < 0) {
165 if (mkdir(path, 0775) < 0) {
166 alert(_("could not create directory %s\n%s"), path, wstrerror(errno));
167 return False;
168 } else {
169 wlog(_("created directory %s"), path);
170 }
171 }
172
173 if (access(path, R_OK | W_OK | X_OK) == 0) {
174 return True;
175 }
176 wsyserror("bad access to directory %s", path);
177
178 if (!fatal) {
179 struct stat buf;
180
181 if (stat(path, &buf) < 0) {
182 alert(_("The directory %s could not be stat()ed. Please make sure\n"
183 "it exists and is accessible."), path);
184 return False;
185 }
186
187 if (!S_ISDIR(buf)) {
188 char *newName = renameName(path);
189
190 if (ask(_("Rename"), _("OK"), _("Cancel"),
191 _("A directory named %s needs to be created but a file with\n"
192 "the same name already exists. The file will be renamed to\n"
193 "%s and the directory will be created."), path, newName)) {
194
195 if (rename(path, newName) < 0) {
196 alert(_("Could not rename %s to %s:%s"), path, newName, wstrerror(errno));
197 }
198 }
199 wfree(newName);
200
201 return False;
202 }
203 if (!(buf.st_mode & S_IRWXU)) {
204 if (chmod(path, (buf.st_mode & 00077) | 7) < 0) {
205 return False;
206 }
207 }
208
209 return checkDir(path, True);
210 }
211
212 showFileError(errno, True, path);
213
214 return False;
215 }
216
217 Bool checkFile(char *path)
218 {
219 if (access(path, F_OK | R_OK | W_OK) == 0) {
220 return True;
221 }
222
223 showFileError(errno, False, path);
224
225 return False;
226 }
227
228 Bool checkCurrentSetup(char *home)
229 {
230 char path[1024];
231 char *p;
232
233 if (!checkDir(home, False)) {
234 wlog("couldnt make directory %s", home);
235 return False;
236 }
237
238 for (p = RequiredDirectories; p != NULL; p++) {
239 sprintf(path, "%s%s", home, p);
240 if (!checkDir(p, False)) {
241 wlog("couldnt make directory %s", p);
242 return False;
243 }
244 }
245
246 for (p = RequiredFiles; p != NULL; p++) {
247 sprintf(path, "%s%s", home, p);
248 if (!checkFile(p, False)) {
249 return False;
250 }
251 }
252
253 return True;
254 }
255
256 Bool copyAllFiles(char *gsdir)
257 {
258 FILE *f;
259 char path[2048];
260 char file[256];
261 char target[2048];
262
263 /* copy misc data files */
264
265 sprintf(path, "%s/USER_FILES", DATADIR);
266
267 f = fopen(path, "rb");
268 while (!feof(f)) {
269 if (!fgets(file, 255, f)) {
270 break;
271 }
272 sprintf(path, "%s/%s", DATADIR, file);
273 sprintf(target, "%s/Library/WindowMaker/%s", gsdir, file);
274 if (!copyFile(path, target)) {
275 return False;
276 }
277 }
278 fclose(f);
279
280 /* copy auto{start,finish} scripts */
281
282 /* select and copy menu */
283
284 /* copy Defaults stuff */
285
286 sprintf(path, "%s/USER_FILES", ETCDIR);
287
288 f = fopen(path, "rb");
289 while (!feof(f)) {
290 if (!fgets(path, 255, f)) {
291 break;
292 }
293 sprintf(path, "%s/%s", ETCDIR, file);
294 sprintf(target, "%s/Defaults/%s", gsdir, file);
295 if (!copyFile(path, target)) {
296 return False;
297 }
298 }
299 fclose(f);
300
301 /* setup .xinitrc */
302
303 }
304
305 void showFinishSplash(char *gsdir)
306 {
307 #if 0
308 WMWindow *win;
309
310 win = WMCreateWindow(scr, "finished");
311 #endif
312 }
313
314 int main(int argc, char **argv)
315 {
316 Display *dpy;
317 char *gsdir;
318 int i;
319
320 for (i = 1; i < argc; i++) {
321 if (strcmp(argv[i], "-display") == 0) {
322 i++;
323 if (i >= argc) {
324 wwarning(_("too few arguments for %s"), argv[i - 1]);
325 exit(0);
326 }
327 DisplayName = argv[i];
328 } else if (strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "--version") == 0) {
329 puts(PROG_VERSION);
330 exit(0);
331 }
332 }
333
334 WMInitializeApplication("WMSetup", &argc, argv);
335
336 dpy = XOpenDisplay("");
337 if (!dpy) {
338 printf("could not open display\n");
339 exit(1);
340 }
341
342 scr = WMCreateScreen(dpy, DefaultScreen(dpy));
343
344 gsdir = wusergnusteppath();
345
346 /* check directory structure and copy files */
347 if (access(gsdir, F_OK) != 0) {
348 if (!ask(_("Window Maker"), _("OK"), _("Cancel"),
349 _("Window Maker will create a directory named %s, where\n"
350 "it will store it's configuration files and other data."), gsdir)) {
351 alert(_("Window Maker will be started in 'static' mode, where\n"
352 "it will use default configuration and will not write\n"
353 "any information to disk."));
354 return 1;
355 }
356 }
357
358 if (checkCurrentSetup(gsdir)) {
359 printf(_("%s: wmaker configuration files already installed\n"), argv[0]);
360 return 0;
361 }
362
363 if (!copyAllFiles(gsdir)) {
364 alert(_("An error occurred while doing user specific setup of\n"
365 "Window Maker. It will be started in 'static' mode, where\n"
366 "the default configuration will be used and it will not write\n"
367 "any information to disk."));
368 return 1;
369 }
370
371 showFinishSplash(gsdir);
372
373 return 0;
374 }
375 #endif