vfs: check userland buffers before reading them.
[haiku.git] / src / apps / mail / People.cpp
blobb8650c80274d8bd8fe8d2377c7612cdd6c7fc114
1 /*
2 * Copyright 2015-2016, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "People.h"
9 #include <stdio.h>
11 #include <Autolock.h>
12 #include <Node.h>
15 static BString
16 PersonName(BNode& node)
18 BString fullName;
19 node.ReadAttrString("META:name", &fullName);
21 return fullName;
25 static void
26 AddPersonAddresses(BNode& node, BStringList& addresses)
28 BString email;
29 if (node.ReadAttrString("META:email", &email) != B_OK || email.IsEmpty())
30 return;
32 addresses.Add(email);
34 // Support for 3rd-party People apps
35 for (int i = 2; i < 99; i++) {
36 char attr[32];
37 snprintf(attr, sizeof(attr), "META:email%d", i);
39 if (node.ReadAttrString(attr, &email) != B_OK)
40 break;
42 addresses.Add(email);
47 static void
48 AddPersonGroups(BNode& node, BStringList& groups)
50 BString groupString;
51 if (node.ReadAttrString("META:group", &groupString) != B_OK
52 || groupString.IsEmpty()) {
53 return;
56 int first = 0;
57 while (first < groupString.Length()) {
58 int end = groupString.FindFirst(',', first);
59 if (end < 0)
60 end = groupString.Length();
62 BString group;
63 groupString.CopyInto(group, first, end - first);
64 group.Trim();
65 groups.Add(group);
67 first = end + 1;
72 // #pragma mark - Person
75 Person::Person(const entry_ref& ref)
77 BNode node(&ref);
78 if (node.InitCheck() != B_OK)
79 return;
81 fName = PersonName(node);
82 AddPersonAddresses(node, fAddresses);
83 AddPersonGroups(node, fGroups);
87 Person::~Person()
92 bool
93 Person::IsInGroup(const char* group) const
95 for (int32 index = 0; index < CountGroups(); index++) {
96 if (GroupAt(index) == group)
97 return true;
99 return false;
103 // #pragma mark - PersonList
106 PersonList::PersonList(QueryList& query)
108 fQueryList(query),
109 fPersons(10, true)
111 fQueryList.AddListener(this);
115 PersonList::~PersonList()
117 fQueryList.RemoveListener(this);
121 void
122 PersonList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t node)
124 BAutolock locker(this);
126 Person* person = new Person(ref);
127 fPersons.AddItem(person);
128 fPersonMap.insert(std::make_pair(node_ref(ref.device, node), person));
132 void
133 PersonList::EntryRemoved(QueryList& source, const node_ref& nodeRef)
135 BAutolock locker(this);
137 PersonMap::iterator found = fPersonMap.find(nodeRef);
138 if (found != fPersonMap.end()) {
139 Person* person = found->second;
140 fPersonMap.erase(found);
141 fPersons.RemoveItem(person);
146 // #pragma mark - GroupList
149 GroupList::GroupList(QueryList& query)
151 fQueryList(query)
153 fQueryList.AddListener(this);
157 GroupList::~GroupList()
159 fQueryList.RemoveListener(this);
163 void
164 GroupList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t _node)
166 BNode node(&ref);
167 if (node.InitCheck() != B_OK)
168 return;
170 BAutolock locker(this);
172 BStringList groups;
173 AddPersonGroups(node, groups);
175 for (int32 index = 0; index < groups.CountStrings(); index++) {
176 BString group = groups.StringAt(index);
178 StringCountMap::iterator found = fGroupMap.find(group);
179 if (found != fGroupMap.end())
180 found->second++;
181 else {
182 fGroupMap[group] = 1;
183 fGroups.Add(group);
187 // TODO: sort groups
191 void
192 GroupList::EntryRemoved(QueryList& source, const node_ref& nodeRef)
194 // TODO!