bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-inetutils] TFTP portability (Was: Present release goals)


From: Mats Erik Andersson
Subject: [bug-inetutils] TFTP portability (Was: Present release goals)
Date: Thu, 20 Oct 2011 21:40:15 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

lördag den 15 oktober 2011 klockan 08:22 skrev Alfred M. Szmidt detta:
>        * tftpd failing for IPv4-mapped-to-IPv6 [2].
>          (Ignore for the time being problems in OpenSolaris.)
> 
> Can we check for this situation in configure.ac somehow?
> 
> #if !defined __sun__
>    filename = cp = tp->th_stuff;
> #else /* __sun__ */
>   filename = cp = (char *) &(tp->th_stuff);
> #endif /* __sun__ */

The following excerpt for OpenSolaris is relevant

   /* <arpa/tftp.h>  for OpenSolaris/NexentaCore. */
   struct       tftphdr {
        short           th_opcode;      /* packet type */
        ushort_t        th_block;       /* block # */
        char            th_data[1];     /* data or error string */
   };
   
   #define      th_code         th_block        /* error code overlay on 
tu_block */
   #define      th_stuff        th_block        /* ditto */
   
   #define      th_msg          th_data

For GNU/Linux, GNU/kFreeBSD, OpenBSD, and FreeBSD, corresponding header
file segment is essentially (the packing is GNU-specific)

   /* GNU/*, OpenBSD, FreeBSD */
   struct       tftphdr {
        short   th_opcode;                      /* packet type */
        union {
                unsigned short  tu_block;       /* block # */
                short   tu_code;                /* error code */
                char    tu_stuff[1];            /* request packet stuff */
        } __attribute__ ((__packed__)) th_u;
        char    th_data[1];                     /* data or error string */
   } __attribute__ ((__packed__));
   
   #define      th_block        th_u.tu_block
   #define      th_code         th_u.tu_code
   #define      th_stuff        th_u.tu_stuff
   #define      th_msg          th_data

The patch reproduced below is able to produce our TFTP client
with correct functionality in GNU/kFreeBSD, OpenBSD, and
OpenSolaris. I use the presence of "union th_u" as marker.

Best regards,
  Mats


diff --git a/configure.ac b/configure.ac
index c818dfa..6d513fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -546,6 +546,14 @@ IU_CHECK_MEMBERS([struct hostent.h_addr_list], , , 
[#include <netdb.h>])
 
 IU_CHECK_MEMBERS([struct stat.st_blksize])
 
+dnl OpenSolaris does not use a union for `struct tftphdr.th_u'.
+dnl As a consequence `struct tftphdr.th_stuff' is a macro
+dnl resolving to a `ushort_t'. BSD and Linux produce `char *'.
+IU_CHECK_MEMBERS([struct tftphdr.th_u], , ,
+                [#include <sys/types.h>
+                 #include <sys/socket.h>
+                 #include <arpa/tftp.h>])
+
 ### Checks for compiler characteristics.
 AM_C_PROTOTYPES dnl FIXME: Does inetutils even compile on pre-ANSI compilers?
 AC_C_CONST
diff --git a/src/tftp.c b/src/tftp.c
index 62c7540..ac07afc 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -1067,7 +1067,11 @@ makerequest (int request, const char *name, struct 
tftphdr *tp,
   register char *cp;
 
   tp->th_opcode = htons ((u_short) request);
+#if HAVE_STRUCT_TFTPHDR_TH_U
   cp = tp->th_stuff;
+#else
+  cp = (char *) &(tp->th_stuff);
+#endif
   strcpy (cp, name);
   cp += strlen (name);
   *cp++ = '\0';
@@ -1144,7 +1148,11 @@ tpacket (const char *s, struct tftphdr *tp, int n)
     case RRQ:
     case WRQ:
       n -= 2;
+#if HAVE_STRUCT_TFTPHDR_TH_U
       file = cp = tp->th_stuff;
+#else
+      file = cp = (char *) &(tp->th_stuff);
+#endif
       cp = strchr (cp, '\0');
       printf ("<file=%s, mode=%s>\n", file, cp + 1);
       break;
diff --git a/src/tftpd.c b/src/tftpd.c
index 49e7ae6..a592154 100644
--- a/src/tftpd.c
+++ b/src/tftpd.c
@@ -332,7 +332,11 @@ tftp (struct tftphdr *tp, int size)
   register struct formats *pf;
   char *filename, *mode;
 
+#if HAVE_STRUCT_TFTPHDR_TH_U
   filename = cp = tp->th_stuff;
+#else
+  filename = cp = (char *) &(tp->th_stuff);
+#endif
 again:
   while (cp < buf + size)
     {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]