libexplain  1.4.D001
libexplain/buffer/errno/getaddrinfo.c
Go to the documentation of this file.
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 : */