changed indentation to use spaces only
[wmaker-crm.git] / util / wmsetup.c
blobc486bbc3c630b649192edeb718fa1e2862ce3d98
1 /* wmsetup.c- create wmaker config file dir structure and copy default
2 * config files.
4 * Copyright (c) 2000-2003 Alfredo K. Kojima
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.
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.
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.
20 #if 1
21 int
22 main()
25 #else
26 #define PROG_VERSION "wmsetup 0.0 (Window Maker)"
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <unistd.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
36 #include <WINGs/WINGs.h>
38 #include "../src/config.h"
42 char *RequiredDirectories[] = {
43 "/Defaults",
44 "/.AppInfo",
45 "/Library",
46 "/Library/Icons",
47 "/Library/WindowMaker",
48 "/Library/WindowMaker/Backgrounds",
49 "/Library/WindowMaker/IconSets",
50 "/Library/WindowMaker/Pixmaps",
51 "/Library/WindowMaker/SoundSets",
52 "/Library/WindowMaker/Sounds",
53 "/Library/WindowMaker/Styles",
54 "/Library/WindowMaker/Themes",
55 NULL
59 char *RequiredFiles[] = {
60 "/Defaults/WindowMaker",
61 "/Defaults/WMWindowAttributes",
62 NULL
67 WMScreen *scr;
71 #define wlog wwarning
74 #if 0
75 void
76 wlog(const char *msg, ...)
78 va_list args;
79 char buf[MAXLINE];
81 va_start(args, msg);
83 vsprintf(buf, msg, args);
84 puts(buf);
86 va_end(args);
88 #endif
91 void
92 alert(const char *msg, ...)
94 va_list args;
95 char buffer[2048];
97 va_start(args, msg);
99 vsprintf(buf, msg, args);
101 WMRunAlertPanel(scr, NULL, _("Error"),
102 buffer, _("OK"), NULL, NULL);
104 va_end(args);
108 Bool
109 ask(char *title, char *yes, char *no, const char *msg, ...)
111 va_list args;
112 char buffer[2048];
114 va_start(args, msg);
116 vsprintf(buf, msg, args);
118 WMRunAlertPanel(scr, NULL, title,
119 buffer, yes, no, NULL);
121 va_end(args);
125 char*
126 renameName(char *path)
128 char *buf = wmalloc(strlen(path)+8);
129 int i;
131 sprintf(buf, "%s~", path);
133 if (access(buf, F_OK) < 0) {
134 return buf;
137 for (i = 0; i < 10; i++) {
138 sprintf(buf, "%s~%i", path, i);
140 if (access(buf, F_OK) < 0) {
141 return buf;
145 sprintf(buf, "%s~", path);
147 return buf;
152 void
153 showFileError(int error, Bool directory, char *path)
155 switch (error) {
156 case EACCESS:
157 if (directory) {
158 alert(_("The directory %s needs to be fully accessible, but is\n"
159 "not. Make sure all of it's parent directories have\n"
160 "read and execute permissions set."), path);
161 } else {
162 alert(_("The file %s needs to be fully accessible, but is not.\n"
163 "Make sure it has read and write permissions set and\n"
164 "all of it's parent directories have read and execute\n"
165 "permissions."), path);
167 break;
169 case EROFS:
170 alert(_("The %s %s is in a read-only file system, but it needs to be\n"
171 "writable. Start wmaker with the --static command line option."),
172 directory ? _("directory") : _("file"), path);
173 break;
175 default:
176 alert(_("An error occurred while accessing the %s %s. Please make sure\n"
177 "it exists and is accessible.\n%s"),
178 directory ? _("directory") : _("file"), path,
179 wstrerror(error));
180 break;
186 Bool
187 checkDir(char *path, Bool fatal)
189 if (access(path, F_OK) < 0) {
190 if (mkdir(path, 0775) < 0) {
191 alert(_("could not create directory %s\n%s"), path,
192 wstrerror(errno));
193 return False;
194 } else {
195 wlog(_("created directory %s"), path);
199 if (access(path, R_OK|W_OK|X_OK) == 0) {
200 return True;
202 wsyserror("bad access to directory %s", path);
204 if (!fatal) {
205 struct stat buf;
207 if (stat(path, &buf) < 0) {
208 alert(_("The directory %s could not be stat()ed. Please make sure\n"
209 "it exists and is accessible."), path);
210 return False;
213 if (!S_ISDIR(buf)) {
214 char *newName = renameName(path);
216 if (ask(_("Rename"), _("OK"), _("Cancel"),
217 _("A directory named %s needs to be created but a file with\n"
218 "the same name already exists. The file will be renamed to\n"
219 "%s and the directory will be created."),
220 path, newName)) {
222 if (rename(path, newName) < 0) {
223 alert(_("Could not rename %s to %s:%s"),
224 path, newName, wstrerror(errno));
227 wfree(newName);
229 return False;
231 if (!(buf.st_mode & S_IRWXU)) {
232 if (chmod(path, (buf.st_mode & 00077)|7) < 0) {
233 return False;
237 return checkDir(path, True);
240 showFileError(errno, True, path);
242 return False;
248 Bool
249 checkFile(char *path)
251 if (access(path, F_OK|R_OK|W_OK) == 0) {
252 return True;
255 showFileError(errno, False, path);
257 return False;
262 Bool
263 checkCurrentSetup(char *home)
265 char path[1024];
266 char *p;
268 if (!checkDir(home, False)) {
269 wlog("couldnt make directory %s", home);
270 return False;
273 for (p = RequiredDirectories; p != NULL; p++) {
274 sprintf(path, "%s%s", home, p);
275 if (!checkDir(p, False)) {
276 wlog("couldnt make directory %s", p);
277 return False;
281 for (p = RequiredFiles; p != NULL; p++) {
282 sprintf(path, "%s%s", home, p);
283 if (!checkFile(p, False)) {
284 return False;
288 return True;
293 Bool
294 copyAllFiles(char *gsdir)
296 FILE *f;
297 char path[2048];
298 char file[256];
299 char target[2048];
301 /* copy misc data files */
303 sprintf(path, "%s/USER_FILES", DATADIR);
305 f = fopen(path, "rb");
306 while (!feof(f)) {
307 if (!fgets(file, 255, f)) {
308 break;
310 sprintf(path, "%s/%s", DATADIR, file);
311 sprintf(target, "%s/Library/WindowMaker/%s", gsdir, file);
312 if (!copyFile(path, target)) {
313 return False;
316 fclose(f);
318 /* copy auto{start,finish} scripts */
321 /* select and copy menu */
324 /* copy Defaults stuff */
326 sprintf(path, "%s/USER_FILES", ETCDIR);
328 f = fopen(path, "rb");
329 while (!feof(f)) {
330 if (!fgets(path, 255, f)) {
331 break;
333 sprintf(path, "%s/%s", ETCDIR, file);
334 sprintf(target, "%s/Defaults/%s", gsdir, file);
335 if (!copyFile(path, target)) {
336 return False;
339 fclose(f);
341 /* setup .xinitrc */
347 void
348 showFinishSplash(char *gsdir)
350 #if 0
351 WMWindow *win;
353 win = WMCreateWindow(scr, "finished");
354 #endif
359 main(int argc, char **argv)
361 Display *dpy;
362 char *gsdir;
363 int i;
365 for (i=1; i<argc; i++) {
366 if (strcmp(argv[i], "-display")==0) {
367 i++;
368 if (i>=argc) {
369 wwarning(_("too few arguments for %s"), argv[i-1]);
370 exit(0);
372 DisplayName = argv[i];
373 } else if (strcmp(argv[i], "-version")==0
374 || strcmp(argv[i], "--version")==0) {
375 puts(PROG_VERSION);
376 exit(0);
380 WMInitializeApplication("WMSetup", &argc, argv);
382 dpy = XOpenDisplay("");
383 if (!dpy) {
384 printf("could not open display\n");
385 exit(1);
388 scr = WMCreateScreen(dpy, DefaultScreen(dpy));
390 gsdir = wusergnusteppath();
392 /* check directory structure and copy files */
393 if (access(gsdir, F_OK) != 0) {
394 if (!ask(_("Window Maker"), _("OK"), _("Cancel"),
395 _("Window Maker will create a directory named %s, where\n"
396 "it will store it's configuration files and other data."),
397 gsdir)) {
398 alert(_("Window Maker will be started in 'static' mode, where\n"
399 "it will use default configuration and will not write\n"
400 "any information to disk."));
401 return 1;
405 if (checkCurrentSetup(gsdir)) {
406 printf(_("%s: wmaker configuration files already installed\n"),
407 argv[0]);
408 return 0;
411 if (!copyAllFiles(gsdir)) {
412 alert(_("An error occurred while doing user specific setup of\n"
413 "Window Maker. It will be started in 'static' mode, where\n"
414 "the default configuration will be used and it will not write\n"
415 "any information to disk."));
416 return 1;
419 showFinishSplash(gsdir);
421 return 0;
423 #endif