Tizen 2.0 Release
[framework/web/wrt-commons.git] / modules / utils / src / wrt_utility.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file        wrt_utility.cpp
18  * @version     0.8
19  * @author      Janusz Majnert <j.majnert@samsung.com>
20  * @brief       Implementation of some common utility functions
21  */
22 #include <stddef.h>
23 #include <fts.h>
24 #include <string>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <ctype.h>
29 #include <unistd.h>
30 #include <dpl/log/log.h>
31 #include <dpl/utils/wrt_utility.h>
32
33 void WrtUtilJoinPaths(std::string &joined,
34                       const std::string &parent,
35                       const std::string &child)
36 {
37     size_t parent_len = parent.length();
38     joined = parent;
39     joined += child;
40     //In case someone used windows-style paths
41     std::replace(joined.begin(), joined.end(), '\\', '/');
42
43     if (parent_len != 0 && child.length() != 0) {
44         if (joined[parent_len - 1] != '/' && joined[parent_len] != '/') {
45             joined.insert(parent_len, "/");
46         } else if (joined[parent_len - 1] == '/' && joined[parent_len] ==
47                    '/')
48         {
49             joined.erase(parent_len, 1);
50         }
51     }
52 }
53
54 bool WrtUtilMakeDir(const std::string &newpath, mode_t mode)
55 {
56     size_t pos = 0;
57     int error;
58
59     if (newpath.length() == 0) {
60         return false;
61     }
62
63     std::string path = newpath;
64
65     if (*(path.rbegin()) != '/') {
66         path += '/';
67     }
68
69     while ((pos = path.find('/', pos + 1)) != std::string::npos) {
70         if (mkdir(path.substr(0, pos).c_str(), mode) != 0) {
71             error = errno;
72             if (error == EEXIST) {
73                 continue;
74             }
75             LogWarning(__PRETTY_FUNCTION__ << ": failed to create directory "
76                                            << path.substr(0, pos)
77                                            << ". Error: "
78                                            << strerror(error));
79             return false;
80         }
81     }
82     return true;
83 }
84
85 bool WrtUtilRemove(const std::string &path)
86 {
87     FTS *fts;
88     FTSENT *ftsent;
89     bool rv = true;
90     int error = 0;
91     char * const paths[] = { const_cast<char * const>(path.c_str()), NULL };
92
93     if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) {
94         //ERROR
95         error = errno;
96         LogWarning(__PRETTY_FUNCTION__ << ": fts_open failed with error: "
97                                        << strerror(error));
98         return false;
99     }
100
101     while ((ftsent = fts_read(fts)) != NULL) {
102         switch (ftsent->fts_info) {
103         case FTS_D:
104             //directory in preorder - do nothing
105             break;
106         case FTS_DP:
107             //directory in postorder - remove
108             if (rmdir(ftsent->fts_accpath) != 0) {
109                 error = errno;
110                 LogWarning(__PRETTY_FUNCTION__
111                            << ": rmdir failed with error: "
112                            << strerror(error));
113                 rv = false;
114             }
115             break;
116         case FTS_DC:
117         case FTS_F:
118         case FTS_NSOK:
119         case FTS_SL:
120         case FTS_SLNONE:
121         case FTS_DEFAULT:
122             //regular files and other objects that can safely be removed
123             if (unlink(ftsent->fts_accpath) != 0) {
124                 error = errno;
125                 LogWarning(__PRETTY_FUNCTION__
126                            << ": unlink failed with error: "
127                            << strerror(error));
128                 rv = false;
129             }
130             break;
131         case FTS_NS:
132             LogWarning(__PRETTY_FUNCTION__
133                        << ": couldn't get stat info for file: "
134                        << ftsent->fts_path
135                        << ". The error was: "
136                        << strerror(ftsent->fts_errno));
137             rv = false;
138             break;
139         case FTS_DOT:
140         case FTS_DNR:
141         case FTS_ERR:
142         default:
143             LogWarning(__PRETTY_FUNCTION__
144                        << ": traversal failed with error: "
145                        << strerror(ftsent->fts_errno));
146             rv = false;
147             break;
148         }
149     }
150
151     if (fts_close(fts) == -1) {
152         error = errno;
153         LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: "
154                                        << strerror(error));
155         rv = false;
156     }
157     return rv;
158 }
159
160 bool WrtUtilFileExists(const std::string &path)
161 {
162     struct stat tmp;
163     if (stat(path.c_str(), &tmp) == 0) {
164         return S_ISREG(tmp.st_mode);
165     } else {
166         return false;
167     }
168 }
169
170 bool WrtUtilDirExists(const std::string &path)
171 {
172     struct stat tmp;
173     if (stat(path.c_str(), &tmp) == 0) {
174         return S_ISDIR(tmp.st_mode);
175     } else {
176         return false;
177     }
178 }
179