Fixed a nasty but minor bug in config_user_path. EEXIST was being
[neverball] / share / base_config.c
1 /*
2  * Copyright (C) 2003 Robert Kooima
3  *
4  * NEVERBALL is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 #include <SDL.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <math.h>
21
22 #include "base_config.h"
23 #include "glext.h"
24 #include "vec3.h"
25
26 /*---------------------------------------------------------------------------*/
27
28 /* Define the mkdir symbol. */
29
30 #ifdef _WIN32
31 #include <direct.h>
32 #else
33 #include <sys/stat.h>
34 #endif
35
36 /*---------------------------------------------------------------------------*/
37
38 static char data_path[MAXSTR];
39 static char user_path[MAXSTR];
40
41 /*
42  * Given  a path  and a  file name  relative to  that path,  create an
43  * absolute path name and return a temporary pointer to it.
44  */
45 static const char *config_file(const char *path, const char *file)
46 {
47     static char absolute[MAXSTR];
48
49     size_t d = strlen(path);
50
51     strncpy(absolute, path, MAXSTR - 1);
52     strncat(absolute, "/",  MAXSTR - d - 1);
53     strncat(absolute, file, MAXSTR - d - 2);
54
55     return absolute;
56 }
57
58 static int config_test(const char *path, const char *file)
59 {
60     if (file)
61     {
62         FILE *fp;
63
64         if ((fp = fopen(config_file(path, file), "r")))
65         {
66             fclose(fp);
67             return 1;
68         }
69         return 0;
70     }
71     return 1;
72 }
73
74 const char *config_data(const char *file)
75 {
76     return config_file(data_path, file);
77 }
78
79 const char *config_user(const char *file)
80 {
81     return config_file(user_path, file);
82 }
83
84 /*---------------------------------------------------------------------------*/
85
86 /*
87  * Attempt to find  the game data directory.  Search  the command line
88  * parameter,  the environment,  and the  hard-coded default,  in that
89  * order.  Confirm it by checking for presence of the named file.
90  */
91 int config_data_path(const char *path, const char *file)
92 {
93     char *dir;
94
95     if (path && config_test(path, file))
96     {
97         strncpy(data_path, path, MAXSTR);
98         return 1;
99     }
100
101     if ((dir = getenv("NEVERBALL_DATA")) && config_test(dir, file))
102     {
103         strncpy(data_path, dir, MAXSTR);
104         return 1;
105     }
106
107     if (CONFIG_DATA && config_test(CONFIG_DATA, file))
108     {
109         strncpy(data_path, CONFIG_DATA, MAXSTR);
110         return 1;
111     }
112
113     return 0;
114 }
115
116 /*
117  * Determine the location of  the user's home directory.  Ensure there
118  * is a  directory there for  storing configuration, high  scores, and
119  * replays.
120  *
121  * HACK: under Windows just assume the user has permission to write to
122  * the data  directory.  This is  more reliable than trying  to divine
123  * anything reasonable from the environment.
124  */
125 int config_user_path(const char *file)
126 {
127 #ifdef _WIN32
128     size_t d = strlen(data_path);
129
130     strncpy(user_path, data_path,   MAXSTR - 1);
131     strncat(user_path, "\\",        MAXSTR - d - 1);
132     strncat(user_path, CONFIG_USER, MAXSTR - d - 2);
133
134     if ((mkdir(user_path) == 0) || (errno == EEXIST))
135         if (config_test(user_path, file))
136             return 1;
137 #else
138     char *dir;
139
140     if ((dir = getenv("HOME")))
141     {
142         size_t d = strlen(dir);
143
144         strncpy(user_path, dir,         MAXSTR - 1);
145         strncat(user_path, "/",         MAXSTR - d - 1);
146         strncat(user_path, CONFIG_USER, MAXSTR - d - 2);
147     }
148
149     if ((mkdir(user_path, 0777) == 0) || (errno == EEXIST))
150         if (config_test(user_path, file))
151             return 1;
152 #endif
153
154     return 0;
155 }
156
157 /*---------------------------------------------------------------------------*/