tizen beta release
[framework/web/wrt-commons.git] / modules / vcore / src / vcore / ReferenceValidator.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 #include <dirent.h>
17 #include <errno.h>
18 #include <fstream>
19 #include <memory>
20
21 #include <dpl/errno_string.h>
22 #include <dpl/log/log.h>
23
24 #include "Base64.h"
25 #include "ReferenceValidator.h"
26
27 namespace {
28 const char *SPECIAL_SYMBOL_CURRENT_DIR = ".";
29 const char *SPECIAL_SYMBOL_UPPER_DIR = "..";
30 const char *SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE = "author-signature.xml";
31 const char *REGEXP_DISTRIBUTOR_SIGNATURE = "^signature[1-9][0-9]*\\.xml";
32 } // namespace anonymous
33
34 namespace ValidationCore {
35 ReferenceValidator::ReferenceValidator(const std::string &dirpath) :
36     m_dirpath(dirpath),
37     m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
38 {
39 }
40
41 ReferenceValidator::Result ReferenceValidator::checkReferences(
42         const SignatureData &signatureData)
43 {
44     return dfsCheckDirectories(signatureData, std::string());
45 }
46
47 ReferenceValidator::Result ReferenceValidator::dfsCheckDirectories(
48         const SignatureData &signatureData,
49         const std::string &directory)
50 {
51     DIR *dp;
52     struct dirent *dirp;
53     std::string currentDir = m_dirpath + directory;
54
55     if ((dp = opendir(currentDir.c_str())) == NULL) {
56         LogError("Error opening directory: " << currentDir.c_str());
57         m_errorDescription = currentDir;
58         return ERROR_OPENING_DIR;
59     }
60
61     for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
62         if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_CURRENT_DIR)) {
63             continue;
64         }
65
66         if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_UPPER_DIR)) {
67             continue;
68         }
69
70         if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
71             !strcmp(dirp->d_name,
72                     SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE) &&
73             signatureData.isAuthorSignature()) {
74             continue;
75         }
76
77         if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
78             isDistributorSignature(dirp->d_name)) {
79             continue;
80         }
81
82         if (dirp->d_type == DT_DIR) {
83             LogDebug("Open directory: " << (directory + dirp->d_name));
84             std::string tmp_directory = directory + dirp->d_name + "/";
85             Result result = dfsCheckDirectories(signatureData, tmp_directory);
86             if (result != NO_ERROR) {
87                 closedir(dp);
88                 return result;
89             }
90         } else if (dirp->d_type == DT_REG) {
91             LogDebug("Found     file: " << (directory + dirp->d_name));
92             const ReferenceSet &referenceSet = signatureData.getReferenceSet();
93             if (referenceSet.end() ==
94                 referenceSet.find(directory + dirp->d_name)) {
95                 closedir(dp);
96                 m_errorDescription = directory + dirp->d_name;
97                 return ERROR_REFERENCE_NOT_FOUND;
98             }
99         } else {
100             LogError("Unknown file type.");
101             closedir(dp);
102             m_errorDescription = directory + dirp->d_name;
103             return ERROR_UNSUPPORTED_FILE_TYPE;
104         }
105     }
106
107     if (errno != 0) {
108         m_errorDescription = DPL::GetErrnoString();
109         LogError("readdir failed. Errno code: " << errno <<
110                  " Description: " << m_errorDescription);
111         closedir(dp);
112         return ERROR_READING_DIR;
113     }
114
115     closedir(dp);
116
117     return NO_ERROR;
118 }
119 }