1 /* gobby - A GTKmm driven libobby client
2 * Copyright (C) 2005, 2006 0x539 dev group
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this program; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <cstring>
20 #include <stdexcept>
21 #include "unix.hpp"
22
23 namespace
24 {
25 const size_t UNIX_PATH_MAX = Gobby::Unix::Address::UNIX_PATH_MAX;
26 const size_t NAME_LENGTH = Gobby::Unix::AbstractAddress::NAME_LENGTH;
27
28 // Makes a byte sequence required by sockaddr_un out of
29 // a unique byte order to identify the socket.
30 class UniqueName
31 {
32 public:
UniqueName(const char unique_name[NAME_LENGTH])33 UniqueName(const char unique_name[NAME_LENGTH])
34 {
35 name[0] = '\0';
36 std::memcpy(name + 1, unique_name, NAME_LENGTH);
37 }
38
data()39 const char* data() { return name; }
40
41 private:
42 char name[UNIX_PATH_MAX];
43 };
44 }
45
Address()46 Gobby::Unix::Address::Address():
47 net6::address()
48 {
49 sockaddr_un* unaddr = new sockaddr_un;
50 addr = reinterpret_cast<sockaddr*>(unaddr);
51
52 unaddr->sun_family = AF_UNIX;
53 }
54
Address(const char * un_path,size_t len)55 Gobby::Unix::Address::Address(const char* un_path, size_t len):
56 net6::address()
57 {
58 if(len > UNIX_PATH_MAX)
59 {
60 throw std::logic_error(
61 "Gobby::Unix::Address::Address:\n"
62 "Given address path exceeds maximum"
63 );
64 }
65
66 sockaddr_un* unaddr = new sockaddr_un;
67 addr = reinterpret_cast<sockaddr*>(unaddr);
68
69 unaddr->sun_family = AF_UNIX;
70 std::memcpy(unaddr->sun_path, un_path, len);
71 }
72
Address(const sockaddr_un * other)73 Gobby::Unix::Address::Address(const sockaddr_un* other):
74 net6::address()
75 {
76 addr = reinterpret_cast<sockaddr*>(new sockaddr_un);
77 std::memcpy(addr, other, sizeof(sockaddr_un) );
78 }
79
Address(const Address & other)80 Gobby::Unix::Address::Address(const Address& other)
81 {
82 addr = reinterpret_cast<sockaddr*>(new sockaddr_un);
83 std::memcpy(addr, other.cobj(), sizeof(sockaddr_un) );
84 }
85
~Address()86 Gobby::Unix::Address::~Address()
87 {
88 delete addr;
89 addr = NULL;
90 }
91
clone() const92 net6::address* Gobby::Unix::Address::clone() const
93 {
94 return new Address(*this);
95 }
96
get_name() const97 std::string Gobby::Unix::Address::get_name() const
98 {
99 if(reinterpret_cast<sockaddr_un*>(addr)->sun_path[0] == '\0')
100 return "<abstract namespace address>";
101
102 return reinterpret_cast<sockaddr_un*>(addr)->sun_path;
103 }
104
get_size() const105 socklen_t Gobby::Unix::Address::get_size() const
106 {
107 return sizeof(sockaddr_un);
108 }
109
operator =(const sockaddr_un * other)110 Gobby::Unix::Address& Gobby::Unix::Address::operator=(const sockaddr_un* other)
111 {
112 std::memcpy(addr, other, sizeof(sockaddr_un) );
113 return *this;
114 }
115
operator =(const Address & other)116 Gobby::Unix::Address& Gobby::Unix::Address::operator=(const Address& other)
117 {
118 if(&other == this)
119 return *this;
120
121 std::memcpy(addr, other.cobj(), sizeof(sockaddr_un) );
122 return *this;
123 }
124
125 Gobby::Unix::AbstractAddress::
AbstractAddress(const char unique_name[NAME_LENGTH])126 AbstractAddress(const char unique_name[NAME_LENGTH]):
127 Address(UniqueName(unique_name).data(), UNIX_PATH_MAX)
128 {
129 }
130
FileAddress(const char * filename)131 Gobby::Unix::FileAddress::FileAddress(const char* filename):
132 Address(filename, strlen(filename) + 1)
133 {
134 }
135