Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
On Windows version of the function getpath(), translate the errno ENOTDIR to ENOENT...
[simgrid.git] / tools / tesh2 / src / getpath.c
1 #include <com.h>\r
2 \r
3 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
4 \r
5 /*#include <stdlib.h>\r
6 #include <string.h>\r
7 \r
8 */\r
9 \r
10 #include <sys/types.h>\r
11 #include <sys/stat.h>\r
12 \r
13 #ifndef WIN32\r
14 #include <pwd.h>\r
15 #else\r
16 #endif\r
17 \r
18 #include <errno.h>\r
19 #include <getpath.h>\r
20 \r
21 #ifndef PATH_MAX\r
22 #define PATH_MAX 255\r
23 #endif\r
24 \r
25 #ifndef WIN32\r
26 int\r
27 getpath(const char* file, char** path)\r
28 {\r
29         char buffer1[PATH_MAX + 1] = {0};\r
30         char buffer2[PATH_MAX + 1] = {0};\r
31         char buffer3[PATH_MAX + 1] = {0};       \r
32         char *p1,*p2;\r
33         size_t len = strlen(file);\r
34         char* last_delimiter = NULL;\r
35         struct stat buffer = {0};               \r
36         \r
37         strncpy(buffer1, file, len);    \r
38         \r
39         /* remove the /////// */\r
40         while((p1 = strstr(buffer1, "//"))) \r
41         {\r
42                 if(p1[2]) \r
43                         strcpy(p1, p1 + 1); \r
44                 else \r
45                         p1[1] = '\0';\r
46         }\r
47         \r
48         if(*buffer1 == '~') \r
49         {\r
50                 for(p2 = buffer2, p1 = buffer1 + 1; *p1 && (*p1 != '/'); *p2++ = *p1++);\r
51                         *p2 = '\0';                             \r
52                 \r
53                 if(buffer2[0] == '\0') \r
54                 {\r
55                         char* home = getenv("HOME");\r
56         \r
57                         if(home) \r
58                         {\r
59                                 strcpy(buffer2, home);          \r
60                         } \r
61                         else \r
62                         {\r
63                                 struct passwd* pw = getpwuid(getuid());  \r
64                                 \r
65                                 if(!pw) \r
66                                 {\r
67                                         *path = NULL;\r
68                                         return -1;      \r
69                                 }\r
70                                 \r
71                                 strcpy(buffer2,pw->pw_dir);     \r
72                         }\r
73                         \r
74                         strcat(buffer2, p1);\r
75                 } \r
76                 \r
77         }\r
78         else if (buffer1[0] != '/') \r
79         {\r
80         \r
81                 getcwd(buffer2, PATH_MAX + 1);  \r
82                 \r
83                 if(buffer1[0] == '.' && buffer1[1] == '/') \r
84                 {       /* replace */\r
85                         strcat(buffer2, &buffer1[1]);           \r
86                 } \r
87                 else \r
88                 {       \r
89                         strcat(buffer2, "/");                   \r
90                         strcat(buffer2, buffer1);               \r
91                 }\r
92         } \r
93         else \r
94         {       \r
95                 strcpy(buffer2, buffer1);                       /* copy */\r
96         }\r
97                 \r
98         /*\r
99          * check for /..\r
100          */\r
101         while((p1 = strstr( buffer2, "/.." ))) \r
102         {\r
103                 for( p2 = p1; --p2 > buffer2 && *p2 != '/'; );\r
104                 \r
105                 if (*(p1 + 3)) \r
106                         memmove(p2, p1+3, strlen(p1+3)+1);\r
107                 else \r
108                         *p2 = '\0';\r
109         }\r
110         \r
111         /*\r
112          * try to find links, and resolve them.\r
113          */\r
114         p1 = strtok( buffer2, "/" );\r
115         \r
116         *buffer3 = '\0';\r
117         \r
118         while(p1) \r
119         {\r
120                 strcat( buffer3, "/" );\r
121                 strcat( buffer3, p1 );\r
122                 \r
123                 len = readlink(buffer3, buffer1, PATH_MAX);\r
124                 \r
125                 if (len != -1) \r
126                 {\r
127                         *(buffer1 + len) = '\0';\r
128                         strcpy(buffer3, buffer1 );\r
129                 }\r
130                 \r
131                 p1 = strtok( NULL, "/" );\r
132         }\r
133         \r
134         if(stat(buffer3, &buffer) || !S_ISREG(buffer.st_mode))\r
135         {\r
136                 *path = NULL;\r
137                 errno = ENOENT;\r
138                 return -1;\r
139         }                                                               \r
140                 \r
141         last_delimiter = strrchr(buffer3, '/');\r
142         \r
143         len = strlen(buffer3);\r
144         \r
145         if(last_delimiter)\r
146                 len -=strlen(last_delimiter);                    \r
147         \r
148         *path = (char*) calloc(len + 1, sizeof(char));\r
149         \r
150         if(!(*path))\r
151         {\r
152                 *path = NULL;\r
153                 return -1;\r
154         }\r
155                 \r
156         strncpy(*path, buffer3, len);\r
157 \r
158         return len;\r
159 }\r
160 \r
161 int\r
162 translatepath(const char* totranslate, char** translated)\r
163 {\r
164         char buffer1[PATH_MAX + 1] = {0};               \r
165         char buffer2[PATH_MAX + 1] = {0};\r
166         char buffer3[PATH_MAX + 1] = {0};       \r
167         char *p1,*p2;\r
168         size_t len;     \r
169         struct stat buffer = {0};\r
170         \r
171         len = strlen(totranslate);                                              \r
172         \r
173         strncpy(buffer1, totranslate, len);     \r
174         \r
175         if(!strcmp(buffer1,"."))\r
176         {\r
177                 *translated = getcwd(NULL,0);\r
178                 return strlen(*translated);\r
179         }\r
180         else if(!strcmp(buffer1, "/.."))\r
181         {\r
182                 *translated = strdup("/");\r
183                 return strlen(*translated);\r
184         }\r
185         \r
186         while((p1 = strstr(buffer1, "//"))) \r
187                 if(p1[2]) \r
188                         strcpy(p1, p1 + 1); \r
189                 else \r
190                         p1[1] = '\0';\r
191         \r
192         if (buffer1[0] == '~') \r
193         {\r
194                 for (p2 = buffer2, p1 = buffer1 + 1; *p1 && (*p1 != '/'); *(p2++) = *(p1++));\r
195                 \r
196                 *p2 = '\0';                             \r
197                 \r
198                 if(buffer2[0] == '\0') \r
199                 {\r
200                         char* home = getenv("HOME");\r
201         \r
202                         if(home) \r
203                         {\r
204                                 strcpy(buffer2, home);\r
205                         } \r
206                         else \r
207                         {\r
208                                 struct passwd* pw = getpwuid(getuid());  /* get entry */\r
209                                 \r
210                                 if(!pw)\r
211                                 {\r
212                                         *translated = NULL; \r
213                                         return -1;\r
214                                 }\r
215                                 \r
216                                 strcpy(buffer2,pw->pw_dir);     \r
217                         }\r
218                         \r
219                         strcat(buffer2, p1);\r
220                 } \r
221         }\r
222         else if (*buffer1 != '/') \r
223         {\r
224         \r
225                 getcwd(buffer2, PATH_MAX + 1);\r
226                 \r
227                 if (*buffer1 == '.' && *(buffer1 + 1) == '/') \r
228                 {\r
229                         strcat(buffer2, buffer1+1);             \r
230                 } \r
231                 else \r
232                 {       \r
233                         strcat(buffer2, "/");                   \r
234                         strcat(buffer2, buffer1);               \r
235                 }\r
236         } \r
237         else \r
238         {       \r
239                 strcpy(buffer2, buffer1);                       \r
240         }\r
241         \r
242         /*\r
243          * check for /..\r
244          */\r
245         while((p1 = strstr( buffer2, "/.." ))) \r
246         {\r
247                 for( p2 = p1; --p2 > buffer2 && *p2 != '/'; );\r
248                 \r
249                 if (*(p1 + 3)) \r
250                         memmove(p2, p1+3, strlen(p1+3)+1);\r
251                 else \r
252                         *p2 = '\0';\r
253         }\r
254         \r
255         /*\r
256          * try to find links.\r
257          */\r
258         p1 = strtok( buffer2, "/" );\r
259         \r
260         \r
261         *buffer3 = '\0';\r
262         \r
263         while(p1) \r
264         {\r
265                 strcat( buffer3, "/" );\r
266                 strcat( buffer3, p1 );\r
267                 \r
268                 len = readlink(buffer3, buffer1, PATH_MAX);\r
269                 \r
270                 if (len != -1) \r
271                 {\r
272                         *(buffer1 + len) = '\0';\r
273                         strcpy(buffer3, buffer1 );\r
274                 }\r
275                 \r
276                 p1 = strtok( NULL, "/" );\r
277         }\r
278         \r
279         if (!(*buffer3)) \r
280                 strcpy(buffer3, "/" );          \r
281         \r
282         len = strlen(buffer3);\r
283         \r
284         if(stat(buffer3, &buffer) || !S_ISDIR(buffer.st_mode))\r
285         {\r
286                 *translated = NULL;\r
287                 errno = ENOTDIR;\r
288                 return -1;\r
289         }\r
290                                  \r
291         \r
292         *translated = (char*) calloc(len + 1, sizeof(char));\r
293         \r
294         if(!(*translated))\r
295         {\r
296                 *translated = NULL;\r
297                 return -1;\r
298         }\r
299         \r
300         strncpy(*translated, buffer3, len);\r
301         \r
302         return len;\r
303 }\r
304 #else\r
305 /*int\r
306 getpath(const char* file, char** path)\r
307 {\r
308         DWORD len;\r
309         char* part = NULL;\r
310         char buffer[PATH_MAX + 1] = {0}; \r
311         struct stat info = {0};\r
312 \r
313         \r
314         len = GetFullPathName(file, PATH_MAX, buffer, &part );\r
315         \r
316         if(!len)\r
317         {\r
318                 *path = NULL;\r
319                 return -1;\r
320         }\r
321         \r
322         if(stat(buffer, &info) || !S_ISREG(info.st_mode))\r
323         {\r
324                 *path = NULL;\r
325                 errno = ENOENT;\r
326                 return -1;\r
327         }               \r
328         \r
329         *path = (char*)calloc(strlen(buffer) - strlen(part), sizeof(char));\r
330 \r
331 \r
332         *path = strncpy(*path, buffer, strlen(buffer) - strlen(part) - 1);\r
333 \r
334         return (int)(strlen(buffer) - strlen(part) -1);\r
335 }*/\r
336 \r
337 int\r
338 getpath(const char* file, char** path)\r
339 {\r
340         char buf1[PATH_MAX + 1] = {0};\r
341         char buf2[PATH_MAX + 1] = {0};\r
342         struct stat info = {0};\r
343 \r
344         char* delimiter;\r
345         \r
346         if(!file)\r
347         {\r
348                 *path = NULL;\r
349                 return -1;\r
350         }\r
351 \r
352         delimiter = strrchr(file,'/');\r
353 \r
354         if(!delimiter)\r
355                 delimiter = strrchr(file,'\\');\r
356 \r
357         if(!delimiter)\r
358         {\r
359                 *path = getcwd(NULL,0);\r
360         }\r
361         else\r
362         {\r
363                 strncpy(buf2, file, (delimiter - file));\r
364 \r
365                 if(translatepath(buf2, path) < 0)\r
366                 {\r
367                         if(errno == ENOTDIR)\r
368                                 errno = ENOENT;\r
369 \r
370                         return -1;\r
371                 }\r
372         }\r
373 \r
374         sprintf(buf1,"%s\\%s", *path, delimiter ? delimiter + 1 : file);\r
375 \r
376         \r
377         if(stat(buf1, &info) || !S_ISREG(info.st_mode))\r
378         {\r
379                 free(*path);\r
380                 *path = NULL;\r
381                 errno = ENOENT;\r
382                 return -1;\r
383         }               \r
384         \r
385         return (int) strlen(*path);\r
386 }\r
387 \r
388 \r
389 int\r
390 translatepath(const char* totranslate, char** translated)\r
391 {\r
392         char buffer1[PATH_MAX + 1] = {0};               \r
393         char buffer2[PATH_MAX + 1] = {0};\r
394         char *p1;\r
395         int i, len;\r
396         \r
397         struct stat stat_buf = {0};\r
398 \r
399         len = (int)strlen(totranslate);                                         \r
400         \r
401         strncpy(buffer1, totranslate, len);\r
402 \r
403         while((p1 = strstr(buffer1, "//"))) \r
404                 if(p1[2]) \r
405                         strcpy(p1, p1 + 1); \r
406                 else \r
407                         p1[1] = '\0';\r
408 \r
409         if(buffer1[strlen(buffer1) - 1] == '/' || buffer1[strlen(buffer1) - 1] == '\\')\r
410                 buffer1[strlen(buffer1) - 1] = '\0';\r
411         \r
412         /* return the current directory */\r
413         if(!strcmp(totranslate,".") || !strcmp(totranslate,"./"))\r
414         {\r
415                 *translated = getcwd(NULL,0);\r
416                 return (int)strlen(*translated);\r
417         }\r
418         /* return the previous directory */\r
419         else if(!strcmp(totranslate,"..") || !strcmp(totranslate,"../"))\r
420         {\r
421                 getcwd(buffer1, PATH_MAX + 1);\r
422                 p1 = strrchr(buffer1, '\\');\r
423                 *translated = (char*) calloc((p1 - buffer1) + 1, sizeof(char));\r
424                 strncpy(*translated, buffer1, (p1 - buffer1));\r
425                 \r
426                 return (int)strlen(*translated);\r
427         }\r
428         /* return the root directory */\r
429         else if(!strcmp(totranslate, "/"))\r
430         {\r
431                 *translated = getcwd(NULL,0);\r
432                 (*translated)[2] = '\0';\r
433 \r
434                 return (int)strlen(*translated);\r
435         }\r
436         /* it's a relative directory name build the full directory name (directory)*/\r
437         else if( buffer1[0] != '.' && buffer1[0] != '/' && buffer1[1] != ':' && !stat(totranslate, &stat_buf) && S_ISDIR(stat_buf.st_mode))\r
438         {\r
439                 for(i = 0; buffer1[i] !='\0'; i++)\r
440                 {\r
441                         if(buffer1[i] == '/')\r
442                                 buffer2[i] = '\\';\r
443                         else\r
444                                 buffer2[i] = buffer1[i];\r
445                 }\r
446                 \r
447                 memset(buffer1, 0, PATH_MAX + 1);\r
448                 getcwd(buffer1, PATH_MAX + 1);\r
449                 strcat(buffer1,"\\");\r
450                 strcat(buffer1,buffer2);\r
451                 \r
452                 *translated = (char*) calloc(strlen(buffer1) + 1, sizeof(char));\r
453                 strcpy(*translated, buffer1);\r
454 \r
455                 return (int)strlen(*translated);\r
456         }\r
457         else if(buffer1[0] == '~') \r
458         {\r
459                 /* TODO */\r
460                 *translated = NULL;\r
461                 errno = ENOSYS;\r
462                 return -1;\r
463         }\r
464         else if (*buffer1 == '.') \r
465         {\r
466                 _fullpath(buffer2, buffer1, sizeof(buffer1));\r
467         } \r
468         else \r
469                 strcpy(buffer2, buffer1);\r
470         \r
471         if(stat(buffer2, &stat_buf) || !S_ISDIR(stat_buf.st_mode))\r
472         {\r
473                 *translated = NULL;\r
474                 errno = ENOTDIR;\r
475                 return -1;\r
476         }\r
477         \r
478 \r
479         \r
480         len = (int)strlen(buffer2);\r
481         \r
482 \r
483         \r
484         *translated = (char*) calloc(len + 1, sizeof(char));\r
485         strcpy(*translated, buffer2);\r
486         \r
487         if(!(*translated))\r
488         {\r
489                 *translated = NULL;\r
490                 return -1;\r
491         }\r
492 \r
493         return len;\r
494 }\r
495 #endif\r
496 \r
497 \r