1 /***************************************************************************
2
3 copyright : (C) 2006 by mean
4 email : fixounet@free.fr
5 ***************************************************************************/
6
7 /***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16
17 #include <errno.h>
18 #include <string>
19 #include <io.h>
20 #include <direct.h>
21 #include <shlobj.h>
22 #include "ADM_win32.h"
23
24 #include "ADM_default.h"
25
26 extern void simplify_path(char **buf);
27 extern char *ADM_getRelativePath(const char *base0, const char *base1, const char *base2, const char *base3);
28 static char ADM_basedir[1024] = {0};
29 static char ADM_logdir[1024] = {0};
30 static std::string ADM_autodir;
31 static std::string ADM_systemPluginSettings;
32
33 #undef fread
34 #undef fwrite
35 #undef fopen
36 #undef fclose
37
38 /**
39 \fn ADM_getAutoDir
40 \brief Get the directory where auto script are stored. No need to free the string.
41 ******************************************************/
ADM_getAutoDir(void)42 const std::string ADM_getAutoDir(void)
43 {
44 if (ADM_autodir.size())
45 return ADM_autodir;
46 const char *startDir=ADM_RELATIVE_LIB_DIR;
47 const char *s = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "autoScripts");
48 ADM_autodir = std::string(s);
49 delete [] s;
50 s=NULL;
51 return ADM_autodir;
52 }
53 /**
54 \fn ADM_getPluginSettingsDir
55 \brief Get the folder containing the plugin settings (presets etc..)
56 */
ADM_getSystemPluginSettingsDir(void)57 const std::string ADM_getSystemPluginSettingsDir(void)
58 {
59 if(ADM_systemPluginSettings.size())
60 return ADM_systemPluginSettings;
61 const char *startDir=ADM_RELATIVE_LIB_DIR;
62 const char *s = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "pluginSettings");
63 ADM_systemPluginSettings = std::string(s);
64 delete [] s;
65 s=NULL;
66 return ADM_systemPluginSettings;
67 }
68
69
AddSeparator(char * path)70 static void AddSeparator(char *path)
71 {
72 if (path && (strlen(path) < strlen(ADM_SEPARATOR) || strncmp(path + strlen(path) - strlen(ADM_SEPARATOR), ADM_SEPARATOR, strlen(ADM_SEPARATOR)) != 0))
73 strcat(path, ADM_SEPARATOR);
74 }
75
76 /**
77 * \fn char *ADM_getHomeRelativePath(const char *base1, const char *base2=NULL,const char *base3=NULL);
78 * \brief Returns home directory +base 1 + base 2... The return value is a copy, and must be deleted []
79 */
ADM_getHomeRelativePath(const char * base1,const char * base2,const char * base3)80 char *ADM_getHomeRelativePath(const char *base1, const char *base2, const char *base3)
81 {
82 return ADM_getRelativePath(ADM_getBaseDir(), base1, base2, base3);
83 }
84
85
86 /*
87 Get the root directory for .avidemux stuff
88 ******************************************************/
ADM_getBaseDir(void)89 const char *ADM_getBaseDir(void)
90 {
91 return ADM_basedir;
92 }
93
94 /*
95 Get the root directory for .avidemux stuff
96 ******************************************************/
ADM_getLogDir(void)97 const char *ADM_getLogDir(void)
98 {
99 return ADM_logdir;
100 }
101
102 /**
103 * \fn ADM_initBaseDir
104 * \brief ADM_initBaseDir
105 */
ADM_initBaseDir(int argc,char * argv[])106 void ADM_initBaseDir(int argc, char *argv[])
107 {
108 char *home = NULL;
109 char *log = NULL;
110
111 bool portableMode=isPortableMode(argc,argv);
112 // Get the base directory
113
114 if (portableMode)
115 {
116 // Portable mode...
117 home = ADM_getInstallRelativePath(NULL, NULL, NULL);
118 log = ADM_getInstallRelativePath(NULL, NULL, NULL);
119 }
120 else
121 {
122 wchar_t wcHome[MAX_PATH];
123 wchar_t wcLog[MAX_PATH];
124
125 if (SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, wcHome) == S_OK)
126 {
127 int len = wideCharStringToUtf8(wcHome, -1, NULL);
128 home = new char[len];
129
130 wideCharStringToUtf8(wcHome, -1, home);
131 }
132 else
133 {
134 printf("Oops: can't determine the Application Data folder.");
135 home=new char[10];
136 strcpy(home,"c:\\");
137 }
138
139 if (SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, wcLog) == S_OK)
140 {
141 int len = wideCharStringToUtf8(wcLog, -1, NULL);
142 log = new char[len];
143
144 wideCharStringToUtf8(wcLog, -1, log);
145 }
146 else
147 {
148 printf("Oops: can't determine the Local Application Data folder.");
149 log=new char[10];
150 strcpy(log,"c:\\");
151 }
152 }
153
154
155 // Try to open the .avidemux directory
156
157 if (home)
158 {
159 strcpy(ADM_basedir, home);
160 AddSeparator(ADM_basedir);
161
162
163 const char *ADM_DIR_NAME;
164
165 if (portableMode)
166 ADM_DIR_NAME = "settings";
167 else
168 ADM_DIR_NAME = "avidemux";
169
170 strcat(ADM_basedir, ADM_DIR_NAME);
171 strcat(ADM_basedir, ADM_SEPARATOR);
172
173 delete [] home;
174
175 if (ADM_mkdir(ADM_basedir))
176 {
177 printf("Using %s as base directory for prefs, jobs, etc.\n", ADM_basedir);
178 }
179 else
180 {
181 ADM_error("Oops: cannot create the .avidemux directoryi (%s)\n", ADM_basedir);
182 }
183 }
184
185 if (log)
186 {
187 strcpy(ADM_logdir, log);
188 AddSeparator(ADM_logdir);
189
190
191 const char *ADM_DIR_NAME;
192
193 if (portableMode)
194 ADM_DIR_NAME = "settings";
195 else
196 ADM_DIR_NAME = "avidemux";
197
198 strcat(ADM_logdir, ADM_DIR_NAME);
199 strcat(ADM_logdir, ADM_SEPARATOR);
200
201 delete [] log;
202
203 if (ADM_mkdir(ADM_logdir))
204 {
205 printf("Using %s as log directory.\n", ADM_logdir);
206 }
207 else
208 {
209 ADM_error("Oops: cannot create the log directory (%s)\n", ADM_logdir);
210 }
211 }
212 }
213 /**
214 * \fn ADM_getI8NDir
215 */
ADM_getI8NDir(const std::string & flavor)216 const std::string ADM_getI8NDir(const std::string &flavor)
217 {
218 //
219 char *home = ADM_getInstallRelativePath(flavor.c_str(), "i18n", NULL);
220 std::string r=std::string(home);
221 delete [] home;
222 return r;
223 }
224 //--- 8< 8< 8<
225
226 # include <io.h>
227 # include <direct.h>
228 # include <shlobj.h>
229 # include <fcntl.h>
230 # include "ADM_win32.h"
231
232 /*
233
234 ** note: it modifies it's first argument
235 */
simplify_path(char ** buf)236 void simplify_path(char **buf)
237 {
238 unsigned int last1slash = 0;
239 unsigned int last2slash = 0;
240
241 while (!strncmp(*buf, "/../", 4))
242 memmove(*buf, *buf + 3, strlen(*buf + 3) + 1);
243
244 for (unsigned int i = 0; i < strlen(*buf) - 2; i++)
245 while (!strncmp(*buf + i, "/./", 3))
246 memmove(*buf + i, *buf + i + 2, strlen(*buf + i + 2) + 1);
247
248 for (unsigned int i = 0; i < strlen(*buf) - 3; i++)
249 {
250 if (*(*buf + i) == '/')
251 {
252 last2slash = last1slash;
253 last1slash = i;
254 }
255
256 if (!strncmp(*buf + i, "/../", 4))
257 {
258 memmove(*buf + last2slash, *buf + i + 3, strlen(*buf + i + 3) + 1);
259
260 return simplify_path(buf);
261 }
262 }
263 }
264
265
266 /**
267 \fn ADM_PathCanonize
268 \brief Canonize the path, returns a copy of the absolute path given as parameter
269 */
ADM_PathCanonize(const char * tmpname)270 char *ADM_PathCanonize(const char *tmpname)
271 {
272 char path[300];
273 char *out;
274
275 if (!getcwd(path, 300))
276 {
277 fprintf(stderr, "\ngetcwd() failed with: %s (%u)\n", strerror(errno), errno);
278 path[0] = '\0';
279 }
280
281 if (!tmpname || tmpname[0] == 0)
282 {
283 out = new char[strlen(path) + 2];
284 strcpy(out, path);
285 #ifndef _WIN32
286 strcat(out, "/");
287 #else
288 strcat(out, "\\");
289 #endif
290 printf("\n Canonizing null string ??? (%s)\n", out);
291 }
292 else if (tmpname[0] == '/'
293 #if defined(_WIN32)
294 || tmpname[1] == ':'
295 #endif
296 )
297 {
298 out = new char[strlen(tmpname) + 1];
299 strcpy(out, tmpname);
300
301 return out;
302 }
303 else
304 {
305 out = new char[strlen(path) + strlen(tmpname) + 6];
306 strcpy(out, path);
307 #ifndef _WIN32
308 strcat(out, "/");
309 #else
310 strcat(out, "\\");
311 #endif
312 strcat(out, tmpname);
313 }
314
315 simplify_path(&out);
316
317 return out;
318 }
319
320 /**
321 \fn ADM_PathStripName
322 \brief Returns path only /foo/bar.avi -> /foo INPLACE, no copy done
323
324 */
ADM_extractPath(const std::string & str)325 std::string ADM_extractPath(const std::string &str)
326 {
327 std::string p;
328 p=str;
329 size_t idx=p.find_last_of ("\\");
330 if(idx!=std::string::npos)
331 p.resize(idx);
332 return p;
333 }
334
335 /**
336 \fn ADM_GetFileName
337 \brief Get the filename without path. /foo/bar.avi -> bar.avi INPLACE, NO COPY
338
339 */
ADM_getFileName(const std::string & str)340 const std::string ADM_getFileName(const std::string &str)
341 {
342 size_t idx=str.find_last_of ("\\");
343 size_t idx2=str.find_last_of ("/");
344
345
346 // no / nor \
347
348 if(idx2==std::string::npos && idx==std::string::npos)
349 return str;
350 // Both, take the further one
351 if(idx2!=std::string::npos && idx!=std::string::npos)
352 if(idx2>idx)
353 return str.substr(idx2+1);
354 else
355 return str.substr(idx+1);
356
357 // Only one found
358 if(idx2!=std::string::npos)
359 return str.substr(idx2+1);
360 return str.substr(idx+1);
361 }
362
363 /**
364 \fn ADM_eraseFile
365 \brief utf8-capable unlink(), so that we can use utf8 string even on win32
366 */
ADM_eraseFile(const char * file)367 uint8_t ADM_eraseFile(const char *file)
368 {
369 int fileNameLength = utf8StringToWideChar(file, -1, NULL);
370 wchar_t *wcFile = new wchar_t[fileNameLength];
371
372 utf8StringToWideChar(file, -1, wcFile);
373
374 bool r = DeleteFileW(wcFile);
375 delete [] wcFile;
376 if(!r)
377 return 0;
378 return 1;
379 }
380
381 // EOF
382