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