Skip to content

Commit a946f78

Browse files
authored
Merge pull request #1476 from fledge-iot/2.6.0RC
2.6.0RC
2 parents a81799b + 422bd66 commit a946f78

135 files changed

Lines changed: 3404 additions & 627 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

C/common/config_category.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <logger.h>
2222
#include <stdexcept>
2323
#include <string_utils.h>
24+
#include <boost/algorithm/string/replace.hpp>
2425

2526

2627
using namespace std;
@@ -872,6 +873,50 @@ vector<string> ConfigCategory::getOptions(const string& name) const
872873
throw new ConfigItemNotFound();
873874
}
874875

876+
/**
877+
* Return the permissions of the configuration category item
878+
*
879+
* @param name The name of the configuration item to return
880+
* @return vector<string> The configuration item permissions
881+
* @throws exception if the item does not exist in the category
882+
*/
883+
vector<string> ConfigCategory::getPermissions(const string& name) const
884+
{
885+
for (unsigned int i = 0; i < m_items.size(); i++)
886+
{
887+
if (name.compare(m_items[i]->m_name) == 0)
888+
{
889+
return m_items[i]->m_permissions;
890+
}
891+
}
892+
throw new ConfigItemNotFound();
893+
}
894+
895+
/**
896+
* Return true if the user has permission to update the named item
897+
*
898+
* @param name The name of the configuration item to return
899+
* @param rolename The name of the user role to test
900+
* @return bool True if the named user can update the configuration item
901+
* @throws exception if the item does not exist in the category
902+
*/
903+
bool ConfigCategory::hasPermission(const std::string& name, const std::string& rolename) const
904+
{
905+
for (unsigned int i = 0; i < m_items.size(); i++)
906+
{
907+
if (name.compare(m_items[i]->m_name) == 0)
908+
{
909+
if (m_items[i]->m_permissions.empty())
910+
return true;
911+
for (auto& perm : m_items[i]->m_permissions)
912+
if (rolename.compare(perm) == 0)
913+
return true;
914+
return false;
915+
}
916+
}
917+
throw new ConfigItemNotFound();
918+
}
919+
875920
/**
876921
* Return if the configuration item is a string item
877922
*
@@ -1300,6 +1345,18 @@ ConfigCategory::CategoryItem::CategoryItem(const string& name,
13001345
}
13011346
}
13021347

1348+
if (item.HasMember("permissions"))
1349+
{
1350+
const Value& permissions = item["permissions"];
1351+
if (permissions.IsArray())
1352+
{
1353+
for (SizeType i = 0; i < permissions.Size(); i++)
1354+
{
1355+
m_permissions.push_back(string(permissions[i].GetString()));
1356+
}
1357+
}
1358+
}
1359+
13031360
if (item.HasMember("items"))
13041361
{
13051362
if (item["items"].IsString())
@@ -1358,6 +1415,7 @@ ConfigCategory::CategoryItem::CategoryItem(const string& name,
13581415
// If it's not a real eject, check the string buffer it is:
13591416
if (!item["value"].IsObject())
13601417
{
1418+
boost::replace_all(m_value, "\\n", "");
13611419
Document check;
13621420
check.Parse(m_value.c_str());
13631421
if (check.HasParseError())
@@ -1466,6 +1524,7 @@ ConfigCategory::CategoryItem::CategoryItem(const string& name,
14661524
// If it's not a real eject, check the string buffer it is:
14671525
if (!item["default"].IsObject())
14681526
{
1527+
boost::replace_all(m_default, "\\n", "");
14691528
Document check;
14701529
check.Parse(m_default.c_str());
14711530
if (check.HasParseError())
@@ -1624,6 +1683,10 @@ ConfigCategory::CategoryItem::CategoryItem(const CategoryItem& rhs)
16241683
m_listSize = rhs.m_listSize;
16251684
m_listItemType = rhs.m_listItemType;
16261685
m_listName = rhs.m_listName;
1686+
for (auto it = rhs.m_permissions.cbegin(); it != rhs.m_permissions.cend(); it++)
1687+
{
1688+
m_permissions.push_back(*it);
1689+
}
16271690
}
16281691

16291692
/**
@@ -1655,6 +1718,18 @@ ostringstream convert;
16551718
convert << "], ";
16561719
}
16571720

1721+
if (m_permissions.size() > 0)
1722+
{
1723+
convert << "\"permissions\" : [ ";
1724+
for (int i = 0; i < m_permissions.size(); i++)
1725+
{
1726+
if (i > 0)
1727+
convert << ",";
1728+
convert << "\"" << m_permissions[i] << "\"";
1729+
}
1730+
convert << "], ";
1731+
}
1732+
16581733
if (m_itemType == StringItem ||
16591734
m_itemType == BoolItem ||
16601735
m_itemType == EnumerationItem ||
@@ -1835,6 +1910,17 @@ ostringstream convert;
18351910
}
18361911
convert << "]";
18371912
}
1913+
if (m_permissions.size() > 0)
1914+
{
1915+
convert << ", \"permissions\" : [ ";
1916+
for (int i = 0; i < m_permissions.size(); i++)
1917+
{
1918+
if (i > 0)
1919+
convert << ",";
1920+
convert << "\"" << m_permissions[i] << "\"";
1921+
}
1922+
convert << "]";
1923+
}
18381924
if (!m_listSize.empty())
18391925
{
18401926
convert << ", \"listSize\" : \"" << m_listSize << "\"";

C/common/file_utils.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Fledge utilities functions for handling files and directories
3+
*
4+
* Copyright (c) 2024 Dianomic Systems
5+
*
6+
* Released under the Apache 2.0 Licence
7+
*
8+
* Author: Ray Verhoeff
9+
*/
10+
11+
#include <stdio.h>
12+
#include <unistd.h>
13+
#include <fcntl.h>
14+
#include <ftw.h>
15+
#include <stdexcept>
16+
#include "file_utils.h"
17+
18+
/**
19+
* Callback for Linux file walk routine 'nftw'
20+
*
21+
* @param filePath File full path
22+
* @param sb struct stat to hold file information
23+
* @param typeflag File type flag: FTW_F = file, FTW_D = directory
24+
* @param ftwbuf struct FTW to hold name offset and file depth
25+
* @return Zero if successful
26+
*/
27+
static int fileDeleteCallback(const char *filePath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
28+
{
29+
return remove(filePath);
30+
}
31+
32+
/**
33+
* Copy a file
34+
*
35+
* @param to Full path of the destination file
36+
* @param from Full path of the source file
37+
* @return Zero if successful
38+
*/
39+
int copyFile(const char *to, const char *from)
40+
{
41+
int fd_to, fd_from;
42+
char buf[4096];
43+
ssize_t nread;
44+
int saved_errno;
45+
46+
fd_from = open(from, O_RDONLY);
47+
if (fd_from < 0)
48+
return -1;
49+
50+
fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666);
51+
if (fd_to < 0)
52+
goto out_error;
53+
54+
while (nread = read(fd_from, buf, sizeof buf), nread > 0)
55+
{
56+
char *out_ptr = buf;
57+
ssize_t nwritten;
58+
59+
do
60+
{
61+
nwritten = write(fd_to, out_ptr, nread);
62+
63+
if (nwritten >= 0)
64+
{
65+
nread -= nwritten;
66+
out_ptr += nwritten;
67+
}
68+
else if (errno != EINTR)
69+
{
70+
goto out_error;
71+
}
72+
} while (nread > 0);
73+
}
74+
75+
if (nread == 0)
76+
{
77+
if (close(fd_to) < 0)
78+
{
79+
fd_to = -1;
80+
goto out_error;
81+
}
82+
close(fd_from);
83+
84+
/* Success! */
85+
return 0;
86+
}
87+
88+
out_error:
89+
saved_errno = errno;
90+
91+
close(fd_from);
92+
if (fd_to >= 0)
93+
close(fd_to);
94+
95+
errno = saved_errno;
96+
return -1;
97+
}
98+
99+
/**
100+
* Create a single directory.
101+
* This routine cannot create a directory tree from a full path.
102+
* This routine throws a std::runtime_error exception if the directory cannot be created.
103+
*
104+
* @param directoryName Full path of the directory to create
105+
*/
106+
void createDirectory(const std::string &directoryName)
107+
{
108+
const char *path = directoryName.c_str();
109+
struct stat sb;
110+
if (stat(path, &sb) != 0)
111+
{
112+
int retcode;
113+
if ((retcode = mkdir(path, S_IRWXU | S_IRWXG)) != 0)
114+
{
115+
std::string exceptionMessage = "Unable to create directory " + directoryName + ": error: " + std::to_string(retcode);
116+
throw std::runtime_error(exceptionMessage.c_str());
117+
}
118+
}
119+
}
120+
121+
/**
122+
* Remove a directory with all subdirectories and files
123+
*
124+
* @param path Full path of the directory
125+
* @return Zero if successful
126+
*/
127+
int removeDirectory(const char *path)
128+
{
129+
return nftw(path, fileDeleteCallback, 64, FTW_DEPTH | FTW_PHYS);
130+
}

0 commit comments

Comments
 (0)