libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2008, 2009, 2011, 2013 Peter Miller 00004 * 00005 * This program is free software; you can redistribute it and/or modify it 00006 * under the terms of the GNU Lesser General Public License as published by 00007 * the Free Software Foundation; either version 3 of the License, or (at 00008 * your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <libexplain/ac/errno.h> 00020 #include <libexplain/ac/netdb.h> 00021 00022 #include <libexplain/buffer/addrinfo.h> 00023 #include <libexplain/buffer/efault.h> 00024 #include <libexplain/buffer/enomem.h> 00025 #include <libexplain/buffer/errno/getaddrinfo.h> 00026 #include <libexplain/buffer/pathname.h> 00027 #include <libexplain/buffer/pointer.h> 00028 #include <libexplain/explanation.h> 00029 #include <libexplain/is_efault.h> 00030 00031 00032 static void 00033 explain_buffer_errcode_getaddrinfo_system_call( 00034 explain_string_buffer_t *sb, int errcode, const char *node, 00035 const char *service, const struct addrinfo *hints, struct addrinfo **res) 00036 { 00037 (void)errcode; 00038 explain_string_buffer_puts(sb, "getaddrinfo(node = "); 00039 explain_buffer_pathname(sb, node); 00040 explain_string_buffer_puts(sb, ", service = "); 00041 explain_buffer_pathname(sb, service); 00042 explain_string_buffer_puts(sb, ", hints = "); 00043 explain_buffer_addrinfo(sb, hints); 00044 explain_string_buffer_puts(sb, ", res = "); 00045 explain_buffer_pointer(sb, res); 00046 explain_string_buffer_putc(sb, ')'); 00047 } 00048 00049 00050 static void 00051 explain_buffer_errcode_getaddrinfo_explanation( 00052 explain_string_buffer_t *sb, int errcode, const char *node, 00053 const char *service, const struct addrinfo *hints, struct addrinfo **res) 00054 { 00055 if (errcode > 0) 00056 { 00057 switch (errcode) 00058 { 00059 case EFAULT: 00060 if (node && explain_is_efault_string(node)) 00061 { 00062 explain_buffer_efault(sb, "node"); 00063 break; 00064 } 00065 if (service && explain_is_efault_string(service)) 00066 { 00067 explain_buffer_efault(sb, "service"); 00068 break; 00069 } 00070 if (hints && explain_is_efault_pointer(hints, sizeof(*hints))) 00071 { 00072 explain_buffer_efault(sb, "hints"); 00073 break; 00074 } 00075 if (res && explain_is_efault_pointer(res, sizeof(*res))) 00076 { 00077 explain_buffer_efault(sb, "res"); 00078 break; 00079 } 00080 break; 00081 00082 case ENOMEM: 00083 explain_buffer_enomem_kernel(sb); 00084 break; 00085 00086 default: 00087 break; 00088 } 00089 return; 00090 } 00091 00092 /* 00093 * http://www.opengroup.org/onlinepubs/009695399/functions/getaddrinfo.html 00094 */ 00095 switch (errcode) 00096 { 00097 #ifdef EAI_ADDRFAMILY 00098 case EAI_ADDRFAMILY: 00099 explain_string_buffer_puts 00100 ( 00101 sb, 00102 "the specified network host does not have any network " 00103 "addresses in the requested address family" 00104 ); 00105 #endif 00106 00107 case EAI_AGAIN: 00108 explain_string_buffer_puts 00109 ( 00110 sb, 00111 "the name server returned a temporary failure indication, " 00112 "future attempts may succeed" 00113 ); 00114 break; 00115 00116 case EAI_BADFLAGS: 00117 explain_string_buffer_puts 00118 ( 00119 sb, 00120 "the ai->ai_flags parameter had an invalid value" 00121 ); 00122 break; 00123 00124 case EAI_FAIL: 00125 explain_string_buffer_puts 00126 ( 00127 sb, 00128 "the name server returned a permanent failure indication " 00129 "when attempting to resolve the name" 00130 ); 00131 break; 00132 00133 case EAI_FAMILY: 00134 explain_string_buffer_puts 00135 ( 00136 sb, 00137 "the requested address family is not supported" 00138 ); 00139 break; 00140 00141 #ifdef EAI_NODATA 00142 case EAI_NODATA: 00143 explain_string_buffer_puts 00144 ( 00145 sb, 00146 "the specified network host exists, but does not have any " 00147 "network addresses defined" 00148 ); 00149 break; 00150 #endif 00151 00152 case EAI_NONAME: 00153 if (!node && !service) 00154 { 00155 explain_string_buffer_puts 00156 ( 00157 sb, 00158 "both node and service are NULL, you have to specify at " 00159 "least one of them" 00160 ); 00161 break; 00162 } 00163 #ifdef AI_NUMERICSERV 00164 if (hints && (hints->ai_flags & AI_NUMERICSERV) && service) 00165 { 00166 explain_string_buffer_puts 00167 ( 00168 sb, 00169 "service was not a numeric port-number string" 00170 ); 00171 break; 00172 } 00173 #endif 00174 if (!service) 00175 { 00176 explain_string_buffer_puts(sb, "the node is not known"); 00177 break; 00178 } 00179 if (!node) 00180 { 00181 explain_string_buffer_puts(sb, "the service is not known"); 00182 break; 00183 } 00184 explain_string_buffer_puts 00185 ( 00186 sb, 00187 "the node or service is not known" 00188 ); 00189 break; 00190 00191 case EAI_SERVICE: 00192 explain_string_buffer_puts 00193 ( 00194 sb, 00195 "the requested service is not available for the requested " 00196 "socket type, it may be available through another socket " 00197 "type" 00198 ); 00199 break; 00200 00201 case EAI_SOCKTYPE: 00202 explain_string_buffer_puts 00203 ( 00204 sb, 00205 "the requested socket type is not supported" 00206 ); 00207 break; 00208 00209 case EAI_SYSTEM: 00210 explain_string_buffer_puts 00211 ( 00212 sb, 00213 "a system error occurred, the error code can be found in errno" 00214 ); 00215 break; 00216 00217 case EAI_MEMORY: 00218 explain_buffer_enomem_user(sb, 0); 00219 break; 00220 00221 #ifdef EAI_OVERFLOW 00222 case EAI_OVERFLOW: 00223 explain_string_buffer_puts 00224 ( 00225 sb, 00226 "an argument buffer overflowed" 00227 ); 00228 break; 00229 #endif 00230 00231 default: 00232 break; 00233 } 00234 } 00235 00236 00237 void 00238 explain_buffer_errcode_getaddrinfo(explain_string_buffer_t *sb, 00239 int errcode, const char *node, const char *service, 00240 const struct addrinfo *hints, struct addrinfo **res) 00241 { 00242 explain_explanation_t exp; 00243 00244 explain_explanation_init(&exp, errcode); 00245 explain_buffer_errcode_getaddrinfo_system_call 00246 ( 00247 &exp.system_call_sb, 00248 errcode, 00249 node, 00250 service, 00251 hints, 00252 res 00253 ); 00254 explain_buffer_errcode_getaddrinfo_explanation 00255 ( 00256 &exp.explanation_sb, 00257 errcode, 00258 node, 00259 service, 00260 hints, 00261 res 00262 ); 00263 explain_explanation_assemble_gai(&exp, sb); 00264 } 00265 00266 00267 /* vim: set ts=8 sw=4 et : */