libexplain  1.4.D001
libexplain/buffer/errno/getdomainname.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2009, 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,but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty
00012  * ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULesser
00013  * 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/stdlib.h>
00021 #include <libexplain/ac/string.h>
00022 #include <libexplain/ac/unistd.h>
00023 
00024 #include <libexplain/buffer/efault.h>
00025 #include <libexplain/buffer/einval.h>
00026 #include <libexplain/buffer/enametoolong.h>
00027 #include <libexplain/buffer/enosys.h>
00028 #include <libexplain/buffer/eperm.h>
00029 #include <libexplain/buffer/errno/generic.h>
00030 #include <libexplain/buffer/errno/getdomainname.h>
00031 #include <libexplain/buffer/is_the_null_pointer.h>
00032 #include <libexplain/buffer/pointer.h>
00033 #include <libexplain/buffer/size_t.h>
00034 #include <libexplain/buffer/software_error.h>
00035 #include <libexplain/explanation.h>
00036 #include <libexplain/host_name_max.h>
00037 
00038 
00039 static void
00040 explain_buffer_errno_getdomainname_system_call(explain_string_buffer_t *sb, int
00041     errnum, char *data, size_t data_size)
00042 {
00043     (void)errnum;
00044     explain_string_buffer_puts(sb, "getdomainname(data = ");
00045     explain_buffer_pointer(sb, data);
00046     explain_string_buffer_puts(sb, ", data_size = ");
00047     explain_buffer_size_t(sb, data_size);
00048     explain_string_buffer_putc(sb, ')');
00049 }
00050 
00051 
00052 static size_t
00053 get_actual_domainname_size(void)
00054 {
00055 #ifdef HAVE_GETDOMAINNAME
00056     /*
00057      * domain name are larger than hostnames,
00058      * so we make the buffer slightly larger.
00059      */
00060     size_t name_size = explain_get_host_name_max() * 4;
00061     char *name = malloc(name_size + 1);
00062     if (name)
00063     {
00064         if (getdomainname(name, name_size) == 0)
00065         {
00066             size_t          result;
00067 
00068             /* paranoia */
00069             name[name_size] = '\0';
00070 
00071             result = strlen(name);
00072             free(name);
00073             return result;
00074         }
00075         free(name);
00076     }
00077 #endif
00078 
00079     /*
00080      * no idea what the length is
00081      */
00082     return 0;
00083 }
00084 
00085 
00086 static void
00087 explain_buffer_errno_getdomainname_explanation(explain_string_buffer_t *sb, int
00088     errnum, char *data, size_t data_size)
00089 {
00090     switch (errnum)
00091     {
00092     case EFAULT:
00093         explain_buffer_efault(sb, "data");
00094         break;
00095 
00096     case EINVAL:
00097         if (!data)
00098         {
00099             explain_buffer_is_the_null_pointer(sb, "data");
00100             break;
00101         }
00102         if ((int)data_size <= 0)
00103         {
00104             explain_buffer_einval_too_small(sb, "data_size", data_size);
00105             break;
00106         }
00107         /* fall through... */
00108 
00109     case ENAMETOOLONG:
00110         /* data_size is smaller than the actual size.  */
00111         {
00112             size_t actual_size = get_actual_domainname_size();
00113             if (actual_size > 0 && data_size < actual_size + 1)
00114             {
00115                 explain_buffer_enametoolong_gethostname
00116                 (
00117                     sb,
00118                     actual_size,
00119                     "data_size"
00120                 );
00121             }
00122             else
00123             {
00124                 explain_buffer_einval_too_small(sb, "data_size", data_size);
00125             }
00126             explain_buffer_software_error(sb);
00127         }
00128         break;
00129 
00130     case ENOSYS:
00131         explain_buffer_enosys_vague(sb, "getdomainname");
00132         break;
00133 
00134     default:
00135         explain_buffer_errno_generic(sb, errnum, "getdomainname");
00136         break;
00137     }
00138 }
00139 
00140 
00141 void
00142 explain_buffer_errno_getdomainname(explain_string_buffer_t *sb, int errnum, char
00143     *data, size_t data_size)
00144 {
00145     explain_explanation_t exp;
00146 
00147     explain_explanation_init(&exp, errnum);
00148     explain_buffer_errno_getdomainname_system_call(&exp.system_call_sb, errnum,
00149         data, data_size);
00150     explain_buffer_errno_getdomainname_explanation(&exp.explanation_sb, errnum,
00151         data, data_size);
00152     explain_explanation_assemble(&exp, sb);
00153 }
00154 
00155 
00156 /* vim: set ts=8 sw=4 et : */