1 //=============================================================================
2 //
3 //   File : KviError.cpp
4 //   Creation date : Sun Jul 02 2000 18:37:02 by Szymon Stefanek
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 //   This program is FREE software. You can redistribute it and/or
10 //   modify it under the terms of the GNU General Public License
11 //   as published by the Free Software Foundation; either version 2
12 //   of the License, or (at your option) any later version.
13 //
14 //   This program is distributed in the HOPE that it will be USEFUL,
15 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 //   See the GNU General Public License for more details.
18 //
19 //   You should have received a copy of the GNU General Public License
20 //   along with this program. If not, write to the Free Software Foundation,
21 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24 
25 #define _KVI_ERROR_CPP_
26 
27 #include "KviError.h"
28 #include "KviLocale.h"
29 #include "kvi_settings.h"
30 
31 #include <QString>
32 
33 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
34 #include <winsock2.h> // for the WSAE* error codes
35 #endif
36 
37 #include <cerrno>
38 
39 #ifdef HAVE_STRERROR
40 #include <string.h> // for strerror()
41 #endif
42 
43 // FIXME: This stuff should basically die and be eventually replaced with some
44 //        helper functions for handling ONLY system errors.
45 //
46 // WARNING: getDescription() is not even thread safe... it will die in the near future
47 
48 const char * g_errorTable[KviError::ErrorCount] = {
49 	__tr_no_lookup("Success"),                                                     // 000: success
50 	__tr_no_lookup("Unknown error"),                                               // 001: unkonwnError
51 	__tr_no_lookup("Internal error"),                                              // 002: internalError
52 	__tr_no_lookup("Unknown command"),                                             // 003: unknownCommand
53 	__tr_no_lookup("Missing closing brace"),                                       // 004: missingClosingBrace
54 	__tr_no_lookup("Unexpected end of command in string"),                         // 005: unexpectedEndInString
55 	__tr_no_lookup("Unexpected end of command in dictionary key"),                 // 006: unexpectedEndInDictionaryKey
56 	__tr_no_lookup("Switch dash without switch letter"),                           // 007: switchDashWithoutSwitchLetter
57 	__tr_no_lookup("Unknown function"),                                            // 008: unknownFunction
58 	__tr_no_lookup("Unexpected end of command in parenthesis"),                    // 009: unexpectedEndInParenthesis
59 	__tr_no_lookup("Unexpected end of command in function parameters"),            // 010: unexpectedEndInFunctionParams
60 	__tr_no_lookup("Missing variable name"),                                       // 011: missingVariableName
61 	__tr_no_lookup("Variable or identifier expected"),                             // 012: variableOrIdentifierExpected
62 	__tr_no_lookup("Left operand is not a number"),                                // 013: leftOperandIsNotANumber
63 	__tr_no_lookup("Multiple operations not supported for numeric operators"),     // 014: multipleOpsNotSupportedForOperator
64 	__tr_no_lookup("Division by zero"),                                            // 015: divisionByZero
65 	__tr_no_lookup("Modulo by zero"),                                              // 016: moduloByZero
66 	__tr_no_lookup("Right operand is not a number"),                               // 017: rightOperandIsNotANumber
67 	__tr_no_lookup("Unterminated expression (missing ')' ?)"),                     // 018: unterminatedExpression
68 	__tr_no_lookup("Unterminated subexpression (Parenthesis mismatch)"),           // 019: unterminatedSubexpression
69 	__tr_no_lookup("Unexpected character"),                                        // 020: unexpectedCharacter
70 	__tr_no_lookup("Unknown operator"),                                            // 021: unknownOperator
71 	__tr_no_lookup("No host to resolve"),                                          // 022
72 	__tr_no_lookup("(DNS internal) Unsupported address family"),                   // 023
73 	__tr_no_lookup("Valid name but the host has no IP address"),                   // 024
74 	__tr_no_lookup("Unrecoverable nameserver error (crashed?)"),                   // 025
75 	__tr_no_lookup("DNS temporary fault (try again)"),                             // 026
76 	__tr_no_lookup("(DNS internal) Bad flags"),                                    // 027
77 	__tr_no_lookup("(DNS internal) Out of memory"),                                // 028
78 	__tr_no_lookup("(DNS internal) Service not supported"),                        // 029
79 	__tr_no_lookup("Unknown node (host not found)"),                               // 030
80 	__tr_no_lookup("(DNS internal) Unsupported socket type"),                      // 031
81 	__tr_no_lookup("DNS query failed"),                                            // 032
82 	__tr_no_lookup("This KVIrc executable has no IPv6 support"),                   // 033
83 	__tr_no_lookup("Host not found"),                                              // 034
84 	__tr_no_lookup("(DNS internal) IPC failure (slave data corrupted)"),           // 035
85 	__tr_no_lookup("Another connection is in progress"),                           // 036
86 	__tr_no_lookup("Invalid IP address"),                                          // 037
87 	__tr_no_lookup("Socket creation failed"),                                      // 038
88 	__tr_no_lookup("Failed to put the socket in non blocking mode"),               // 039
89 	__tr_no_lookup("Bad file descriptor"),                                         // 040
90 	__tr_no_lookup("Out of address space"),                                        // 041
91 	__tr_no_lookup("Connection refused"),                                          // 042
92 	__tr_no_lookup("Kernel networking panic"),                                     // 043
93 	__tr_no_lookup("Connection timed out"),                                        // 044
94 	__tr_no_lookup("Network is unreachable"),                                      // 045
95 	__tr_no_lookup("Broken pipe"),                                                 // 046
96 	__tr_no_lookup("Invalid proxy address"),                                       // 047
97 	__tr_no_lookup("Remote end has closed the connection"),                        // 048
98 	__tr_no_lookup("Invalid IRC context ID"),                                      // 049
99 	__tr_no_lookup("Error loading module"),                                        // 050
100 	__tr_no_lookup("No such module command"),                                      // 051
101 	__tr_no_lookup("No such module function"),                                     // 052
102 	__tr_no_lookup("Left operand is not a dictionary reference"),                  // 053
103 	__tr_no_lookup("Right operand is not a dictionary reference"),                 // 054
104 	__tr_no_lookup("Missing object class name"),                                   // 055
105 	__tr_no_lookup("No such object class"),                                        // 056
106 	__tr_no_lookup("No such object"),                                              // 057
107 	__tr_no_lookup("No such object function"),                                     // 058
108 	__tr_no_lookup("Invalid left operand"),                                        // 059
109 	__tr_no_lookup("Not enough parameters"),                                       // 060
110 	__tr_no_lookup("Integer parameter expected"),                                  // 061
111 	__tr_no_lookup("Invalid parameter"),                                           // 062
112 	__tr_no_lookup("No such file"),                                                // 063
113 	__tr_no_lookup("Open parenthesis expected"),                                   // 064
114 	__tr_no_lookup("Open brace expected"),                                         // 065
115 	__tr_no_lookup("Can't kill a builtin class"),                                  // 066
116 	__tr_no_lookup("The SOCKSv4 protocol lacks IPv6 support"),                     // 067
117 	__tr_no_lookup("Unrecognized proxy reply"),                                    // 068
118 	__tr_no_lookup("Proxy response: auth failed: access denied"),                  // 069
119 	__tr_no_lookup("Proxy response: no acceptable auth method: request rejected"), // 070
120 	__tr_no_lookup("Proxy response: request failed"),                              // 071
121 	__tr_no_lookup("Proxy response: Ident failed"),                                // 072
122 	__tr_no_lookup("Proxy response: Ident not matching"),                          // 073
123 	__tr_no_lookup("Proxy response: general SOCKS failure"),                       // 074
124 	__tr_no_lookup("Proxy response: connection not allowed"),                      // 075
125 	__tr_no_lookup("Proxy response: network unreachable"),                         // 076
126 	__tr_no_lookup("Proxy response: host unreachable"),                            // 077
127 	__tr_no_lookup("Proxy response: connection refused"),                          // 078
128 	__tr_no_lookup("Proxy response: TTL expired"),                                 // 079
129 	__tr_no_lookup("Proxy response: command not supported"),                       // 080
130 	__tr_no_lookup("Proxy response: address type not supported"),                  // 081
131 	__tr_no_lookup("Proxy response: invalid address"),                             // 082
132 	__tr_no_lookup("Invalid port number"),                                         // 083
133 	__tr_no_lookup("Socket not connected"),                                        // 084
134 	__tr_no_lookup("Insufficient resources to complete the operation"),            // 085
135 	__tr_no_lookup("Can't setup a listening socket : bind failed"),                // 086
136 	__tr_no_lookup("Can't resolve the localhost name"),                            // 087
137 	__tr_no_lookup("Unsupported image format"),                                    // 088
138 	__tr_no_lookup("Can't open file for appending"),                               // 089
139 	__tr_no_lookup("Can't open file for writing"),                                 // 090
140 	__tr_no_lookup("File I/O error"),                                              // 091
141 	__tr_no_lookup("Acknowledge error"),                                           // 092
142 	__tr_no_lookup("Can't open file for reading"),                                 // 093
143 	__tr_no_lookup("Can't send a zero-size file"),                                 // 094
144 	__tr_no_lookup("Missing popup name"),                                          // 095
145 	__tr_no_lookup("'item', 'popup', 'label' or 'separator' keyword expected"),    // 096
146 	__tr_no_lookup("Self modification not allowed"),                               // 097
147 	__tr_no_lookup("Feature not available"),                                       // 098
148 	__tr_no_lookup("Unexpected characters in array index"),                        // 099
149 	__tr_no_lookup("Unexpected end in expression"),                                // 100
150 	__tr_no_lookup("Unexpected end in array index"),                               // 101
151 	__tr_no_lookup("Connection through HTTP proxy failed"),                        // 102
152 	__tr_no_lookup("Case, match, regexp, default or break keyword expected"),      // 103
153 	__tr_no_lookup("Access denied"),                                               // 104
154 	__tr_no_lookup("Address already in use"),                                      // 105
155 	__tr_no_lookup("Can't assign the requested address"),                          // 106
156 	__tr_no_lookup("Connection reset by peer"),                                    // 107
157 	__tr_no_lookup("Host unreachable (no route to host)"),                         // 108
158 	__tr_no_lookup("Variable expected"),                                           // 109
159 	__tr_no_lookup("Invalid array index: positive integer expected"),              // 110
160 	__tr_no_lookup("listen() call failed"),                                        // 111
161 	__tr_no_lookup("This executable has been compiled without SSL support"),       // 112
162 	__tr_no_lookup("Secure Socket Layer error"),                                   // 113
163 	__tr_no_lookup("Slash (/) character expected"),                                // 114
164 	__tr_no_lookup("Unknown string manipulation operation"),                       // 115
165 	__tr_no_lookup("Operation aborted"),                                           // 116
166 	__tr_no_lookup("Unexpected token"),                                            // 117
167 	__tr_no_lookup("Scope object already defined (unexpected @)"),                 // 118
168 	__tr_no_lookup("There is no $this pointer in this scope (unexpected @)")       // 119
169 };
170 
171 namespace KviError
172 {
getUntranslatedDescription(KviError::Code eError)173 	const char * getUntranslatedDescription(KviError::Code eError)
174 	{
175 		if((eError < ErrorCount) && (eError >= 0))
176 			return g_errorTable[eError];
177 #ifdef HAVE_STRERROR
178 		if(eError < 0)
179 			return strerror(-eError);
180 #endif
181 		return g_errorTable[KviError::UnknownError];
182 	}
183 
getDescription(KviError::Code eError)184 	QString getDescription(KviError::Code eError)
185 	{
186 		return __tr2qs_no_xgettext(getUntranslatedDescription(eError));
187 	}
188 
translateSystemError(int iErrNo)189 	KviError::Code translateSystemError(int iErrNo)
190 	{
191 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
192 		switch(iErrNo)
193 		{
194 			case EBADF:
195 				return KviError::BadFileDescriptor;
196 				break;
197 			case WSAEINVAL:
198 			case WSAEFAULT:
199 			case EFAULT:
200 				return KviError::OutOfAddressSpace;
201 				break;
202 			case WSAECONNREFUSED:
203 				return KviError::ConnectionRefused;
204 				break;
205 			case WSAENOTSOCK:
206 				return KviError::KernelNetworkingPanic;
207 				break;
208 			case WSAETIMEDOUT:
209 				return KviError::ConnectionTimedOut;
210 				break;
211 			case WSAENETUNREACH:
212 				return KviError::NetworkUnreachable;
213 				break;
214 			case EPIPE:
215 				return KviError::BrokenPipe;
216 				break;
217 			case WSAENOTCONN:
218 				return KviError::SocketNotConnected;
219 				break;
220 			case WSAEACCES:
221 				return KviError::AccessDenied;
222 				break;
223 			case WSAEADDRINUSE:
224 				return KviError::AddressAlreadyInUse;
225 				break;
226 			case WSAEADDRNOTAVAIL:
227 				return KviError::CantAssignRequestedAddress;
228 				break;
229 			case WSAEAFNOSUPPORT:
230 				return KviError::UnsupportedAddressFamily;
231 				break;
232 			case WSAECONNRESET:
233 				return KviError::ConnectionResetByPeer;
234 				break;
235 			case WSAEHOSTUNREACH:
236 				return KviError::HostUnreachable;
237 				break;
238 			// Unhandled error...pass errno to the strerror function
239 			default:
240 				return KviError::UnknownError;
241 				break;
242 		}
243 #else
244 		switch(iErrNo)
245 		{
246 			case EBADF:
247 				return KviError::BadFileDescriptor;
248 				break;
249 			case EFAULT:
250 				return KviError::OutOfAddressSpace;
251 				break;
252 			case ECONNREFUSED:
253 				return KviError::ConnectionRefused;
254 				break;
255 			case ENOTSOCK:
256 				return KviError::KernelNetworkingPanic;
257 				break;
258 			case ETIMEDOUT:
259 				return KviError::ConnectionTimedOut;
260 				break;
261 			case ENETUNREACH:
262 				return KviError::NetworkUnreachable;
263 				break;
264 			case EPIPE:
265 				return KviError::BrokenPipe;
266 				break;
267 			case ENOTCONN:
268 				return KviError::SocketNotConnected;
269 				break;
270 			case ENOBUFS:
271 				return KviError::InsufficientResources;
272 				break;
273 			case ECONNRESET:
274 				return KviError::ConnectionResetByPeer;
275 				break;
276 			case EHOSTUNREACH:
277 				return KviError::HostUnreachable;
278 				break;
279 			// Unhandled error...pass errno to the strerror function
280 			default:
281 				return KviError::UnknownError;
282 				break;
283 		}
284 #endif
285 	}
286 }
287