1 /***************************************************************************
2 * \name ADM_folder_unix.cpp
3 * \author mean (c) 2006/2016
4 ***************************************************************************/
5
6 /***************************************************************************
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 ***************************************************************************/
14
15 #include <dirent.h>
16 #include <errno.h>
17 #include <sys/stat.h>
18 #include <string>
19
20 #if defined(__APPLE__)
21 # include <Carbon/Carbon.h>
22 #else
23 # include <fcntl.h>
24 #endif
25 #include "ADM_default.h"
26
27 #undef fopen
28 #undef mkdir
29
30 /*
31
32 ** note: it modifies it's first argument
33 */
simplify_path(char ** buf)34 void simplify_path(char **buf)
35 {
36 unsigned int last1slash = 0;
37 unsigned int last2slash = 0;
38
39 while (!strncmp(*buf, "/../", 4))
40 memmove(*buf, *buf + 3, strlen(*buf + 3) + 1);
41
42 for (unsigned int i = 0; i < strlen(*buf) - 2; i++)
43 while (!strncmp(*buf + i, "/./", 3))
44 memmove(*buf + i, *buf + i + 2, strlen(*buf + i + 2) + 1);
45
46 for (unsigned int i = 0; i < strlen(*buf) - 3; i++)
47 {
48 if (*(*buf + i) == '/')
49 {
50 last2slash = last1slash;
51 last1slash = i;
52 }
53
54 if (!strncmp(*buf + i, "/../", 4))
55 {
56 memmove(*buf + last2slash, *buf + i + 3, strlen(*buf + i + 3) + 1);
57
58 return simplify_path(buf);
59 }
60 }
61 }
62 /**
63 \fn ADM_fopen
64 \brief utf8 aware fopen, so that we can use utf8 string even on win32
65 */
ADM_fopen(const char * file,const char * mode)66 FILE *ADM_fopen(const char *file, const char *mode)
67 {
68 return fopen(file, mode);
69 }
70
71 /**
72 \fn ADM_eraseFile
73 */
ADM_eraseFile(const char * file)74 uint8_t ADM_eraseFile(const char *file)
75 {
76 if(!unlink(file))
77 return true;
78 return false;
79 }
80
81 /*----------------------------------------
82 Create a directory
83 If it already exists, do nothing
84 ------------------------------------------*/
ADM_mkdir(const char * dirname)85 uint8_t ADM_mkdir(const char *dirname)
86 {
87 DIR *dir = NULL;
88 uint8_t retVal = 0;
89
90 const char* dirname2 = dirname;
91
92 while (true)
93 {
94 // Check it already exists ?
95 dir = opendir(dirname2);
96
97 if (dir)
98 {
99 printf("Directory %s exists.Good.\n", dirname);
100 closedir(dir);
101
102 retVal = 1;
103 break;
104 }
105 printf("Creating dir :%s\n", dirname2);
106 mkdir(dirname2,0755);
107
108 if ((dir = opendir(dirname2)) == NULL)
109 break;
110
111 closedir(dir);
112
113 retVal = 1;
114
115 break;
116 }
117
118 return retVal;
119 }
120 /**
121 * \fn buildDirectoryContent
122 * \brief Returns the content of a dir with the extension ext. The receiving array must be allocated by caller
123 * (just the array, not the names themselves)
124 */
buildDirectoryContent(uint32_t * outnb,const char * base,char * jobName[],int maxElems,const char * ext)125 uint8_t buildDirectoryContent(uint32_t *outnb, const char *base, char *jobName[], int maxElems, const char *ext)
126 {
127 DIR *dir;
128 struct dirent *direntry;
129 int dirmax = 0, len;
130 int extlen = strlen(ext)+1;
131 ADM_assert(extlen>1);
132
133 char *dotted=(char *)admAlloca(extlen+1);
134 strcpy(dotted+1,ext);
135 dotted[0]='.';
136
137 const char *base2 = base;
138
139 dir = opendir(base2);
140
141
142 if (!dir)
143 {
144 return 0;
145 }
146
147
148 while ((direntry = readdir(dir)))
149 {
150 const char *d_name = direntry->d_name;
151
152 len = strlen(d_name);
153
154 if (len < (extlen + 1))
155 continue;
156
157 int xbase = len - extlen;
158
159 if (memcmp(d_name + xbase, dotted, extlen))
160 {
161 printf("ignored: %s\n", d_name);
162 continue;
163 }
164
165 jobName[dirmax] = (char *)ADM_alloc(strlen(base) + strlen(d_name) + 2);
166 strcpy(jobName[dirmax], base);
167 AddSeparator(jobName[dirmax]);
168 strcat(jobName[dirmax], d_name);
169 dirmax++;
170
171 if (dirmax >= maxElems)
172 {
173 printf("[jobs]: Max # of jobs exceeded\n");
174 break;
175 }
176 }
177
178
179 closedir(dir);
180 *outnb = dirmax;
181
182 return 1;
183 }
184
185 /**
186 \fn ADM_PathCanonize
187 \brief Canonize the path, returns a copy of the absolute path given as parameter
188 */
ADM_PathCanonize(const char * tmpname)189 char *ADM_PathCanonize(const char *tmpname)
190 {
191 char path[300];
192 char *out;
193
194 if (!getcwd(path, 300))
195 {
196 fprintf(stderr, "\ngetcwd() failed with: %s (%u)\n", strerror(errno), errno);
197 path[0] = '\0';
198 }
199
200 if (!tmpname || tmpname[0] == 0)
201 {
202 out = new char[strlen(path) + 2];
203 strcpy(out, path);
204 strcat(out, "/");
205 printf("\n Canonizing null string ??? (%s)\n", out);
206 }
207 else if (tmpname[0] == '/' )
208 {
209 out = new char[strlen(tmpname) + 1];
210 strcpy(out, tmpname);
211
212 return out;
213 }
214 else
215 {
216 out = new char[strlen(path) + strlen(tmpname) + 6];
217 strcpy(out, path);
218 strcat(out, "/");
219 strcat(out, tmpname);
220 }
221
222 simplify_path(&out);
223
224 return out;
225 }
226
227 /**
228 \fn ADM_extractPath
229 \brief Returns path only /foo/bar.avi -> /foo
230
231 */
ADM_extractPath(const std::string & str)232 std::string ADM_extractPath(const std::string &str)
233 {
234 std::string p;
235 p=str;
236 size_t idx=p.find_last_of ("/");
237 if(idx!=std::string::npos)
238 p.resize(idx);
239 return p;
240 }
241 /**
242 */
ADM_getFileName(const std::string & str)243 const std::string ADM_getFileName(const std::string &str)
244 {
245 size_t idx=str.find_last_of ("/");
246 if(idx==std::string::npos) return str;
247 return str.substr(idx+1);
248 }
249
250 /**
251 \fn ADM_copyFile
252 */
ADM_renameFile(const char * source,const char * target)253 uint8_t ADM_renameFile(const char *source, const char *target)
254 {
255 if(!rename(source,target)) return true;
256 return false;
257 }
258
259
260 // EOF
261